Recent Releases of phaser

phaser - Phaser v4.0.0 Release Candidate 5

New Features

  • Mask filter now supports scaleFactor parameter, allowing the creation of scaled-down framebuffers. This can save memory in large games, but you must manage scaling logic yourself. Thanks to kimdanielarthur-cowlabs for developing the initial solution.
  • Camera has the new property isObjectInversion, used internally to support special transforms for filters.
  • Shader has the new method renderImmediate, which makes it straightforward to use renderToTexture when the object is not part of a display list, or otherwise needs updating outside the regular render loop.

Improvements

  • Drawing contexts, including filters, can now be larger than 4096 if the current device supports them. Thanks to kimdanielarthur-cowlabs for suggesting this.
  • Balance rounded rectangle corners for smoothness on small corners while preventing excessive tesselation.

Fixes

  • PhysicsGroup.add and StaticPhysicsGroup.add will now check to see if the incoming child already has a body of the wrong type, and if so, will destroy it so the new correct type can be assigned.
  • Blocky filter now has a minimum size of 1, which prevents the object from disappearing.
  • TilemapGPULayer now takes the first tileset if it receives an array of tilesets (which is valid for Tilemaps but not for TilemapGPULayer). Thanks to ChrisCPI for the fix.
  • Filters now correctly transform the camera to focus objects with intricate transforms.
  • Filters now correctly handle parent transforms when focusing to the game camera.
  • DynamicTexture method startCapture now handles nested parent transforms correctly. This is used in Mask, so masks within Container objects should behave correctly too.
  • Children of filtered Container/Layer objects are correctly added to the current camera's renderList. This fixes an issue with input on overlapping interactive objects.

- JavaScript
Published by photonstorm 9 months ago

phaser - Phaser v3.90.0

Version 3.90 - Tsugumi - 23rd May 2025

New Features

  • GameObjects.Rectangle.setRounded is a new method that will allow the Rectangle Shape Game Object to have rounded corners. Pass the radius to set for the corners, or pass a value of zero to disable rounded corners.
  • GameObjects.Rectangle.isRounded is a new read-only boolean that can be used to determine if the Rectangle Shape Game Object has rounded corners, or not.
  • GameObjects.Rectangle.radius is a new read-only number that is the size of the rounded corners. Do not set directly, instead use the method setRounded.
  • Added Phaser.Math.Angle.GetClockwiseDistance() to get the shortest nonnegative angular distance between two angles. PR #7092 (thanks @samme)
  • Added Phaser.Math.Angle.GetCounterClockwiseDistance() gets the shortest nonpositive angular distance between two angles. PR #7092 (thanks @samme)
  • Added Phaser.Math.Angle.GetShortestDistance() gets the shortest signed angular distance between two angles. (This is like Phaser.Math.Angle.ShortestBetween() but in radians.) PR #7092 (thanks @samme)
  • Added Phaser.GameObjects.BitmapText#setDisplaySize method to BitmapText to get the original scaled size of 1. PR #6623 (thanks @samme)
  • Added fallback for Web Audio on Firefox. Firefox doesn't implement positionX, positionY and positionZ properties on the AudioListener instances at the moment. This prevents the follow feature from WebAudioSound to operate on Firefox. PR #7083 (thanks @raaaahman)

Updates

  • The EXPAND Scale Mode has been updated to now clamp the size of the canvas that is created, preventing it from growing too large on landscape ultra-wide displays. Fix #7027 (thanks @leha-games @rexrainbow)
  • An Error will now be thrown if you try to create a DOM Game Object but haven't correctly configured the Game Config (thanks @samme)

Bug Fixes

  • An erroneous console.log was left in the Text Game Object. This has now been removed.
  • Particle emitter color RGB arrays are cleared before repopulating. Fix #7069 (thanks @Golen87 @samme)
  • Phaser.Animations.AnimationFrame correctly uses frame duration when it is set. Fix #7070 (thanks @sylvainpolletvillard)
  • Particle emitter custom moveTo functions can now move particles. Fix #7063 (thanks @samme)
  • Changed ImageCollections default Tileset values from null to undefined. Fix #7053 (thanks @Snoturky)
  • Chained tweens now persist correctly even after calling Phaser.Tweens.BaseTween#stop. Fix #7048 (thanks @FranciscoCaetano88)
  • New left-to-right Text Game Objects now includes the default canvas.dir = 'ltr and context.direction = 'ltr';. Fixes a bug in Chrome 134 & Edge 134 where calling destroy() on a right-to-left Text Game Object prevents the next created left-to-right Text Game Object from rendering. Fix #7077 (thanks @Demeno)
  • Grid Game Objects renders lineWidth correctly in WebGL mode. Fix #7029 (thanks @AlvaroNeuronup)
  • Added collisionMask and collisionCategory checks to Phaser.Physics.Arcade.World#separate to allow individual physics game objects within a physics group to have it's own unique collision categories. Fix #7034 (thanks @frederikocmr)
  • Fixed Arcade Physics bug causing immovable circle objects to move when pushed by polygons. Fix #7054 (thanks @hunkydoryrepair)
  • Fixed createFromTiles to handle multiple tilesets when using sprite sheets. Fix #7122 (thanks @vikerman)
  • Fixed audio files not loading from Base64 data URIs (thanks @bagyoni)

Examples, Documentation, Beta Testing and TypeScript

Thanks to the following for helping with the Phaser Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@justin-calleja @ixonstater @DayKev

- JavaScript
Published by photonstorm about 1 year ago

phaser - Phaser v4.0.0 Release Candidate 4

This update improves performance related to data buffer size, primarily affecting filters, including masks. A game that was bottlenecked by filters on mobile devices may experience speedups of 16x or more. A desktop system, or a scene with no filters, may be broadly unaffected, save for memory savings.

New Features

  • BatchHandlerQuadSingle render node added.
    • This is just a copy of BatchHandlerQuad with space for 1 quad.
    • The rendering system uses this node internally for transferring images in some steps of the filter process.

Changes

  • BatchHandler render nodes now create their own WebGL data buffers.
    • This uses around 5MB of RAM and VRAM in a basic game.
    • Dedicated buffers are an optimum size for batch performance.

Removals

  • WebGLRenderer#genericVertexBuffer and #genericVertexData removed.
    • This frees 16MB of RAM and VRAM.
  • BatchHandlerConfig#createOwnVertexBuffer type property removed.
  • TileSprite no longer supports texture cropping.

Fixes

  • Lighting fixed on rotated or filtered objects.
  • Added missing 'this' value for Group.forEach and StaticGroup.forEach (thanks @TadejZupancic)
  • Fix createFromTiles to handle multiple tilesets when using sprite sheets. Fix #7122 (thanks @vikerman)
  • Fix audio files not loading from Base64 data URIs (thanks @bagyoni)

Documentation / TypeScript Enhancements

Thanks to the following people:

@captain-something @DayKev @ixonstater

- JavaScript
Published by photonstorm about 1 year ago

phaser - Phaser v4.0.0 Release Candidate 3

This release candidate introduces better pixel art controls, and fixes performance issues related to pixel art options.

Updates since RC2:

New Features

  • GameObject#vertexRoundMode added to control vertex pixel rounding on a per-object basis.
    • Options include:
    • "off": Never round vertex positions.
    • "safe": Round vertex positions if the object is "safe": it is rendering with a transform matrix which only affects the position, not other properties such as scale or rotation.
    • "safeAuto" (default): Like "safe", but only if rendering through a camera where roundPixels is enabled.
    • "full": Always round vertex positions. This can cause sprites to wobble if their vertices are not safely aligned with the pixel resolution, e.g. during rotations. This is good for a touch of PlayStation 1 style jank.
    • "fullAuto": Like "full", but only if rendering through a camera where roundPixels is enabled.
    • GameObject#willRoundVertices(camera, onlyTranslated) returns whether vertices should be rounded. In the unlikely event that you need to control vertex rounding even more precisely, you are intended to override this method.
  • Blocky filter added. This is similar to Pixelate, but it picks just a single color from the image, preserving the palette of pixel art. You can also configure the pixel width and height, and offset. This is a good option for pixelating a retro game at high resolution, setting up for additional filters such as CRT emulation.

Changes

  • WebGL2 canvases are now compatible with the WebGL renderer.
  • Optimize multi-texture shader.
    • Shader branching pattern changed to hopefully be more optimal on a wider range of devices.
    • Shader will not request the maximum number of textures if it doesn't need them, improving performance on many mobile devices.
    • Shader no longer performs vertex rounding. This will prevent many situations where a batch was broken up, degrading performance.

Fixes

  • WebGLSnapshot and snapshot functions based on it now return the correct pixel, instead of the one above it (or nothing if they're at the top of the image).
  • ArcadePhysics#closest() and #furthest() are properly defined (thanks @samme).
  • GamepadPlugin.stopListeners and GamepadPlugin.disconnectAll now have guards around them so they won't try to invoke functions on potentially undefined gamepads (thanks @cryonautlex)
  • Arcade Physics OverlapCirc() and OverlapRect() error when useTree is false. Fix #7112 (thanks @samme)

Documentation / TypeScript Enhancements

Thanks to the following people:

@ospira @samme @OuttaBounds @raaaahman

- JavaScript
Published by photonstorm about 1 year ago

phaser - Phaser v4.0.0 Release Candidate 2

Updates since RC1:

New Features

  • RenderConfig#renderNodes allows you to add render nodes at game boot.
  • ShaderQuadConfig#initialUniforms lets you initialize a Shader with uniforms on creation.
  • Shader#setUniform(name, value) lets you set shader program uniforms just once, instead of putting them all into the setupUniforms() method, where some uniforms might be set redundantly after init. This wraps Shader#renderNode.programManager.setUniform.

Changes

  • TextureManager#addDynamicTexture now has forceEven parameter.

Fixes

  • Fix parent transform on filtered objects (e.g. masks inside containers).
  • Fix camera shake.
  • Add typedefs for the { internal, external } structure of Camera#filters (and GameObject#filters).
  • Fix FilterList#addMask docs.
  • In Layer and Container objects, use that object's children for the displayList passed to RenderWebGLSteps.
  • Fix positioning of Group members and offset objects in DynamicTexture#draw.
  • Fix Shadow filter direction.

- JavaScript
Published by photonstorm about 1 year ago

phaser - Phaser v4.0.0 Release Candidate 1

Updates since beta 8:

Changes

  • Mask filter now uses current camera by default.
  • GameObject#enableLighting now works even if the scene light manager is not enabled. The light manager must still be enabled for lights to render, but the game object flag can be set at any time.
  • YieldContext and RebindContext render nodes now unbind all texture units. These nodes are used for external renderer compatibility. An external renderer could change texture bindings, leading to unexpected textures being used, so we force texture rebind.

New Features

  • WebGLSnapshot (used in snapshot functions) supports unpremultiplication, which is on by default. This removes dark fringes on text and objects with alpha.
  • Add chainable setter methods to Filter component: setFiltersAutoFocus, setFiltersFocusContext, setFiltersForceComposite, setRenderFilters.
  • All enhancements from Phaser v3 development have been merged. This includes:
    • Transform#getWorldPoint
    • Layer#getDisplayList
    • DynamicTexture and RenderTexture changes:
    • forceEven parameter forces resolution to be divisible by 2.
    • clear(x, y, width, height) method now takes the listed optional parameters.
    • Rectangle now supports rounded corners.
    • Physics.Matter.Components.Transform#scale for setting scaleX and scaleY together.
    • WebGLRenderer reveals functions around context loss:
    • setExtensions
    • setContextHandlers
    • dispatchContextLost
    • dispatchContextRestored
    • Improvements to tile handling for non-orthogonal tiles.
    • Tween#isNumberTween
    • Many other fixes and tweaks.

Fixes

  • Fix WebGLSnapshot orientation.
  • Fix filters rendering outside intended camera scissor area.
  • Fix reversion in BitmapText kerning.
  • Fix CaptureFrame compatibility with Layer and Container.
  • Fix Grid using old methods. It was supposed to use 'stroke' just like other Shape objects, not a unique 'outline'.
  • Add @return tag to FilterList#addBlend (thanks @phasereditor2d!).
  • Fix RenderSteps parameter propagation into Layer and Container. This resolves some missing render operations in complex situations.
  • Fix DynamicTexture errors when rendering Masks.
  • Fix camera transform matrix order issues, as seen when rendering through transformed cameras.
  • Fix GL scissor sometimes failing to update. The actual issue was, we were storing the screen coordinates, but applying GL coordinates, which can be different in different-sized framebuffers. DrawingContext now takes screen coordinates, and sets GL coordinates in the WebGLGlobalWrapper.

- JavaScript
Published by photonstorm about 1 year ago

phaser - Phaser v4.0.0 Beta 8

Changes

  • Mask Filter now uses world transforms by preference when drawing the mask. This improves expected outcomes when mask objects are inside Containers.

Additions

  • Extend RenderWebGLStep to take the currently rendering object list and index as parameters. This allows render methods to know their context in the display list, which can be useful for optimizing third-party renderers.
    • This takes the place of nextTypeMatch from Phaser v3, but is much more flexible.
  • Add DynamicTexture#capture, for rendering game objects more accurately and with greater control than draw.
  • Add CaptureFrame game object, which copies the current framebuffer to a texture when it renders. This is useful for applying post-processing prior to post.

Fixes

  • Prevent RenderTexture from rendering while it's rendering, thus preventing infinite loops.
  • Fix boundary errors on the Y axis in TilemapGPULayer shader, introduced after switching to GL standard texture orientation.
  • Fix Filters#focusFilters setting camera resolution too late, leading to unexpected results on the first frame.
  • Fix parent matrix application order, resolving unexpected behavior within Containers.
  • Fix FillCamera node being misaligned/missing in cameras rendering to framebuffers.
  • Fix errors when running a scene without the lighting plugin.
  • Fixes to TypeScript documentation: thanks to SBCGames and mikuso for contributions!

- JavaScript
Published by photonstorm about 1 year ago

phaser - Phaser v4.0.0 Beta 7

Major Changes

  • Camera System Rewrite

The camera system rewrite changes the way camera matrices are calculated.

The Phaser 3 camera combined position, rotation, and zoom into Camera#matrix. Camera scroll was appended later.

The new camera system uses two matrices. Camera#matrix is now a combination of rotation, zoom, and scroll. A new Camera#matrixExternal property includes camera position. This allows us to cleanly divide the view from the position.

This change doesn't affect how you set camera properties to change the view. It mostly affects internal systems. However, if you use camera matrices directly, be aware that they have changed.

  • Camera#matrix now includes scroll, and excludes position.
  • Camera#matrixExternal is a new matrix, which includes the position.
  • Camera#matrixCombined is the multiplication of matrix and matrixExternal. This is sometimes relevant.
  • The GetCalcMatrix(src, camera, parentMatrix, ignoreCameraPosition) method now takes ignoreCameraPosition, causing its return value to use the identity matrix instead of the camera's position.
  • GetCalcMatrixResults now includes a matrixExternal property, and factors scroll into the camera and calc matrices.
  • To get a copy of a matrix with scroll factor applied, use TransformMatrix#copyWithScrollFactorFrom(matrix, scrollX, scrollY, scrollFactorX, scrollFactorY). This generally replaces cases where phrases such as spriteMatrix.e -= camera.scrollX * src.scrollFactorX were used.

The new system fixes many issues with nested transforms, filters, and other uses of transforms.

Minor Additions

  • Add documentation explaining how to modify a SpriteGPULayer efficiently.
  • Add SpriteGPULayer#insertMembers method.
  • Add SpriteGPULayer#insertMembersData method.
  • Add SpriteGPULayer#getDataByteSize method.
  • Add non-looping animations to SpriteGPULayer (set animation to loop: false) to support one-time particle effects and dynamic sources.
  • Add creation time to SpriteGPULayer members.
  • Add documentation for writing a Extern#render function.
  • TilemapLayer and TilemapGPULayer now support a parent matrix during rendering.
  • Shape now sets filtersFocusContext = true by default, to prevent clipping stroke off at the edges.

Fixes and Tweaks

  • Fix missing reference to Renderer events in BatchHandler (thanks @mikuso)
  • Fix SpriteGPULayer segment handling (segments changed from 32 to 24 to avoid problems with 32-bit number processing)
  • Allow negative acceleration in SpriteGPULayer member animations using Gravity.
  • Rearrange SpriteGPULayer data encoding.
  • Fix SpriteGPULayer failing to generate frame animations from config objects.
  • Allow TextureSource#setFlipY to affect all textures (except compressed textures, which have fixed orientation).
  • WebGLProgramWrapper now correctly recognizes uniforms with a value of undefined and can recognize if they have not changed and do not need updates.
  • Set roundPixels game option to false by default. It's very easy to get messy results with this option, but it remains available for use cases where it is necessary.
  • Throw an error if DOMElement has no container.
  • Fix TileSprite applying smoothPixelArt game option incorrectly.

- JavaScript
Published by photonstorm about 1 year ago

phaser - Phaser v4.0.0 Beta 6

Additions

  • Add Filter support to Layer.
  • Allow RenderTexture to automatically re-render.
    • DynamicTexture#preserve() allows you to keep the command buffer for reuse after rendering.
    • DynamicTexture#callback() allows you to run callbacks during command buffer execution.
    • RenderTexture.setTextureMode() allows you to set the RenderTexture to automatically re-render during the render loop.

Fixes and Eliminations

  • Fix roundPixels handling in many places, mostly by removing it from irrelevant situations.
    • Remove TransformMatrix#setQuad parameter roundPixels, as it is no longer used.
  • Filters are correctly destroyed along with their owners, unless ignoreDestroy is enabled. This supports multi-owner Filter controllers.
  • WebGLRenderer destroys itself properly.
  • Remove unnecessary transform related to camera scroll.
  • Remove references to Mesh.
  • Fix UV coordinates in Shader.
  • Shader#setTextures() now replaces the texture array, rather than adding to it.
  • Fix SpriteGPULayer#getMember(), which previously multiplied the index by 4.
  • Fix flipX/flipY in Filter#focusFilters.
  • Fix BatchHandlerQuad#run() parameter tintFill, which was set as a Number but should be used as a Boolean.
  • Eliminate rounding in Camera#preRender().

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v3.88.2

Bug Fixes

  • Reverted an incorrect change made to the Scale Manager that prevented the autoCenter: Phaser.Scale.CENTER_BOTH from working.

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v3.88.1

Bug Fixes

  • Fixed ReferenceError: GetFastValueOp is not defined in NumberTweenBuilder (thanks Flow)
  • Reverted incorrect change made to SafeRange array util function.
  • Fixed Array.Utils.GetFirst so it correctly handles a negative start index. Fixes Container.getByName returning null and various other similar methods. Fix #7040 (thanks @XWILKINX)

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v3.88

New Features

  • Transform.getWorldPoint is a new method that will return the World point as a Vector2 of a Game Object, factoring in parents if applicable (thanks @samme)
  • Utils.Array.GetFirst can now search from the end of the array when setting startIndex to -1.
  • DynamicTexture and by extension RenderTexture now have a new boolean property forceEven in their constructor, setSize and resize methods. This will force the given width and height values to be rounded up to the nearest even value. This significantly improves the rendering quality of the render texture in most circumstances, so the flag is true by default. This is a potentially breaking change, so if you know you need an odd sized texture, please set the value to false. Fix #6988 (thanks @rexrainbow)

Updates

  • Tween.isNumberTween is a new boolean property that tells if the Tween is a NumberTween, or not.
  • The TransformMatrix.setTransform method has been updated so that it uses the old way of passing in matrix values for Canvas 2D. This fixes the error "Failed to execute 'setTransform' on 'CanvasRenderingContext2D': 6 arguments required, but only 1 present." in old legacy browsers such as Chromium Embedded Framework. Fix #6965 (thanks @rafa-fie)
  • Handlers for both mousedown and mouseup have been added for unlocking Web Audio. Both events occur before a click event, allowing for earlier audio unlocking on devices that use a mouse (thanks @pavle-goloskokovic)
  • In both the Canvas and WebGL Renderer the background color, as set in the game config, is applied directly to the canvas immediately upon creation, rather than at the first render step. This may avoid some 'flashes' of color in certain circumstances (thanks @pavle-goloskokovic)
  • The Texture Manager will now fail gracefully when a texture isn't created as a result of calling the addBase64 method. Rather than the error "TypeError: null is not an object (evaluating 'texture.source')" is will not return early (thanks @samme)
  • Both TweenBuilder and NumberTweenBuilder have been updated to use GetFastValue for most properties instead of GetValue.
  • The Transform.getWorldTransformMatrix method will now destroy the parent matrix at the end, if it was created within the method.
  • The Arcade Physics Body.setGameObject and StaticBody.setGameObject methods have been updated to do the following: Return if no valid Game Object is passed. Disable and null the body of the existing Game Object if the Body has one. Set the body property, even if it doesn't exist (converts non-physics objects into physics objects). Calls setSize to update the body dimensions to make the new Game Object and finally sets enable based on the given parameter, which is now correctly referenced. The StaticBody version also has a new parameter, enable which matches that of the Dynamic Body and defaults to true (the original state). Fix #6969 (thanks @yongzheng7)
  • The Arcade Physics ArcadeColliderType has been updated to include Physics.Arcade.StaticBody. Fix #6967 (thanks @yongzheng7)
  • Phaser.Types.GameObjects.Text.TextStyle now includes letterSpacing: a positive or negative amount to add to the spacing between characters. Fix #7002 (thanks @Stever1388)
  • Tilemaps.Parsers.Tiled.ParseTilesets, Tilemaps.Parsers.Tiled.BuildTilesetIndex and Tilemaps.ImageCollection.addImage have been updated to include width and height of each individual image. Fix #6990 (thanks @stickleprojects)
  • Tilemaps.Components.RenderDebug and Tilemaps.Parsers.Tiled.BuildTilesetIndex have been updated to include width and height offsets in Image Collections.
  • Added a warning to Tilemaps.Components.GetTilesWithinShape when attempting to use this method with non orthogonal tilemaps.
  • Changed the Cameras.Scene2D.Camera.preRender method from protected to public. Fix #7020 (thanks @zoubingwu)

Bug Fixes

  • TweenData.update will now check if the Tween is a Number Tween and apply the final start/end value to the result on completion, instead of the eased value as calculated by the change made in v3.87.
  • BaseTweenData.duration can now never be zero or less than zero, which would trigger NaN errors. It's now clamped to a minimum of 0.01ms. Fix #6955 (thanks @kainage)
  • Fixed the properties in the FontFileConfig (thanks @samme)
  • Matter.World.update could hang and crash the browser if a large delta value was given to it, such as returning to a long-dormant tab. The Matter Runner config values are now properly passed through, preventing this from happening. Fix #6977 (thanks @ubershmekel @samme)
  • Phaser.Physics.Matter.Components.Transform#scale correctly scales the physics body with the GameObject. Fix #7001 (thanks @Stever1388)
  • Phaser.Textures.Frame.setCropUVs updated crop calculation to include the spriteSourceSize. Fix #6996 (thanks @CrispMind)
  • Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled updated hexagonal tilemaps to correctly calculate the widthInPixels and heightInPixels based on the hexagonal overlapping tiles. Fix #6992 (thanks @ptantiku)
  • Phaser.Display.Color.Interpolate.RGBWithRGB now correctly returns a Phaser.Types.Display.ColorObject that includes r, g, b, a and color values. Fix #6979 (thanks @XWILKINX)
  • Fixed incorrect Arcade Physics circle separation logic for circle to circle, and circle to rectangle collisions. The logic was incorrectly moving only one body, even if both could be moved. Fix #6963 (thanks @samme)
  • Phaser.Plugins.PluginManager automatically boots plugins when the game config render type is set to Phaser.HEADLESS. Fix #6893 (thanks @hubertgrzeskowiak)
  • Tweens created with persist set to true and given a completeDelay value are no longer destroyed and can be replayed. Fix #7008 (thanks @Stever1388)
  • The Tweens.TweenChain onStart event is now dispatched properly. Fix #7007 (thanks @Stever1388)
  • GameObjects.Particles.Zones.DeathZone now uses world position coordinates instead of local position coordinates following the particle emitter position. Fix #7006 (thanks @Stever1388)
  • Merged pull request #7009 from @samme that prevents hanging timer events with repeats and negative delays. Fix #7004 (thanks @Stever1388)
  • When adding a new Tween, passing an event listener callback outside the Phaser.Types.Tweens.TweenBuilderConfig object is now correctly executed without errors. Fix #7003 (thanks @Stever1388)
  • A GameObjects.Text created with wordwrap and with letterSpacing applied now takes into account the provided letterSpacing value to correctly wrap lines. Fix #7002 (thanks @Stever1388)
  • Creating new GameObjects.DOMElement sets the GameObject's displayWidth and displayHeight using its scaleX and scaleY values instead of the DOM elements getBoundingClientRect() values. Fix #6871 (thanks @HawkenKing)
  • Setting scale mode to Phaser.Scale.FIT and autoCenter to Phaser.Scale.CENTER_BOTH correctly centres canvas on iOS devices. Fix #6862 (thanks @HawkenKing)
  • On hex maps, creating a blank layer with the Tilemaps.Tilemap.createBlankLayer method now correctly sets the hexSideLength as loaded from the hex tilemap. Fix #6074 (thanks @wwoods)
  • The Input.InputPlugin.processDragUpEvent now correctly returns x and y coordinates in world space.
  • Animations.AnimationState.play method now prioritises the frameRate property when it is set in the PlayAnimationConfig object over animation data loaded from an external file.
  • Fixed an issue where sounds / music would stop playing in iOS 17.5.1+ or iOS18+ after losing/gaining focus in Safari. The Web Audio Sound Manager will now listen for the 'visible' event and suspend and resume the context as a result. Fix #6829 (thanks @JanAmbrozic @condeagustin)
  • The Layer Game Object method setToTop would throw an exception: getDisplayList is not a function. This method has now been added to the Game Object. Fix #7014 (thanks @leha-games @rexrainbow)
  • Fixed an issue where the Particle EmitterOp defaultEmit() always returned undefined, causing particle problems if you gave only an onUpdate callback. Also if you configured an EmitterOp with onEmit or onUpdate, the op's current value would be incorrect (an object) until the first emit. Fix #7016 (thanks @urueda @samme)

Examples, Documentation, Beta Testing and TypeScript

Thanks to the following for helping with the Phaser Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @justin-calleja

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v4.0.0 Beta 5

As well as bug fixes, beta 5 includes two major components:

  • SpriteGPULayer game object. This advanced renderer is designed to handle millions of background objects.
  • Texture coordinates now match WebGL standards. This should bring greater compatibility with other technologies. Note that compressed textures must be re-compressed to work with this system: ensure that the Y axis starts at the bottom and increases upwards.

Fixes and Improvements

  • Limit roundPixels to only operate when objects are axis-aligned and unscaled. This prevents flicker on transforming objects.
  • Fix TextureSource.resolution being ignored in WebGL.
    • This fixes an issue where increasing text resolution increased text size.
  • Fix DynamicTexture using a camera without the required methods.
  • Remove WebGLAttribLocationWrapper as it is unused.
  • Remove WebGLRenderer.textureIndexes as glTextureUnits.unitIndices now fills this role.
  • Remove dead code and unused/unconnected properties from WebGLRenderer.
  • Switch texture orientation to match WebGL standards.
  • Add SpriteGPULayer game object.

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v4.0.0 Beta 4

Fixes and Improvements

  • Fix Arcade Physics group collisions, nearest and furthest, and static group refresh. Thanks samme!
  • Fail gracefully when a texture isn't created in addBase64()
  • Improve RenderSteps initialization, removing a private method substitution
  • Fix Layer's use of RenderSteps
  • Fix reversion that removed camera zoom on separate axes
  • Fix filter padding precision
  • Fix filter padding offset with internal filters
  • Improve TransformMatrix.setQuad documentation
  • Fix shader not switching when TilemapLayer and TileSprite are in the same scene

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v4.0.0 Beta 3

Thanks to the community feedback in the Phaser Discord we decided to rework the way RenderFilters work:

Previously, the RenderFilters object wrapped game objects to apply Filters. This worked well in several ways, but because it replaced the existing game object, it made object references less reliable.

The decision was made to change Filters to a component on game objects. This is similar to the old FX system, but it is now built into the base GameObject, so it can be used everywhere. Filters are not FX (they're better).

For those who have been using Phaser 4 beta 1 or 2, this will change the way you use filters. The core principles are the same, however: filters are still divided into internal and external lists.

The new way to use filters is thus:

```js // Set up filter systems. gameObject.enableFilters();

// Create filter controllers. const blur = gameObject.filters.internal.addBlur(); ```

When you run enableFilters(), Phaser creates an internal camera to handle the object's filters, and adds a RenderStep function.

By default, when there are no active filters to render, the RenderStep skips straight to renderWebGL. If you want the object to render to a framebuffer without rendering a filter, you can set gameObject.filtersForceComposite = true. This can be useful when you want to composite alpha, e.g. when you have several objects in a Container or Layer and you don't want to see them through each other, you can leave their alpha at 1, set filtersForceComposite, and reduce the alpha of gameObject.filterCamera.

Filters run focusFilters every time they render by default. This differs from RenderFilters.focus, which didn't run every time. This method ensures that the filterCamera is always locked onto the object. Some objects don't have enough properties to accurately lock on to, so the system will guess, and fall back to the screen resolution. You can run gameObject.focusFiltersOverride to manually set the camera target.

In general, this runs much like FX did - but with more control and better compatibility.

For more details about this release, please see the Dev Logs in Issue 211 of our Phaser World newsletter (due out on Friday 27th December)

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v4.0.0 Beta 2

  • Better roundPixels handling via bias.
  • UUIDs for DynamicTexture names.
    • Masks work (again). Big feature!
  • DynamicTexture can resize immediately after creation.
  • Fix shader compilation issues on diverse systems. * Shapes/Graphics should work again in Firefox. * Issues with inTexDatum should be eliminated in affected Linux systems.
  • Fix Extern and extend its rendering potential (see Beam Examples).
  • TileSprite now assigns default dimensions to each dimension separately.
  • BaseFilterShader now accesses loaded shader cache keys correctly.

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v4.0.0 Beta 1

This is the first beta release of Phaser v4.0.0. This build includes the brand new Phaser Beam renderer, that powers all of the WebGL rendering internally. We will be publishing more details about this in the coming days, but for now, you can drop in this build as a direct v3.80+ replacement and see how your game runs! Check out the README for more internal changes.

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v3.87

New Features

  • FontFile is a new File Type loader that allows you to load TTF/OTF fonts directly into Phaser, without the need for a 3rd party web font loader or CSS hacks. The loaded fonts can be used in the Text Game Objects, such as the example below:

```js preload () { this.load.font('Caroni', 'assets/fonts/ttf/caroni.otf', 'opentype'); this.load.font('troika', 'assets/fonts/ttf/troika.otf', 'opentype'); }

create () { this.add.text(32, 32, 'The face of the moon was in shadow.', { fontFamily: 'troika', fontSize: 80, color: '#ff0000' }); this.add.text(150, 350, 'Waves flung themselves at the blue evening.', { fontFamily: 'Caroni', fontSize: 64, color: '#5656ee' }); } ```

Updates

  • The Particle Animation State is now optional. A Particle will not create an Animation State controller unless the anim property exists within the emitter configuration. By not creating the controller it leads to less memory overhead and a much faster clean-up time when destroying particles. Fix #6482 (thanks @samme)
  • Optimized TweenData.update to achieve the same result with my less repetition. Also fixes an issue where a Tween that used a custom ease callback would glitch when the final value was set, as it would be set outside of the ease callback. It's now passed through it, no matter what. Fix #6939 (thanks @SBCGames)

Bug Fixes

  • Fixed the calculation of the index in GetBitmapTextSize that would lead to incorrect indexes vs. the docs and previous releases (thanks @bagyoni)
  • Utils.String.RemoveAt would incorrectly calculate the slice index if it was > 0. It will now remove the correctly specified character.

Examples, Documentation, Beta Testing and TypeScript

Thanks to the following for helping with the Phaser Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@Jessime @drakang4 @BenAfonso @hatchling13

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v3.86.0

Updates

  • RenderTarget.init is a new method that will create the underlying framebuffer and texture for a Render Target. This is called in the constructor only, avoiding the need to call the resize method.
  • Phaser.GameObjects.Container#tempTransformMatrix has been removed. This was an internal private Transform Matrix. It has been replaced by a global single matrix that is used instead. This removes the need for every Container to have its own instance of this temporary matrix, reducing object allocation and memory overhead.
  • BaseCamera.renderRoundPixels is a new read-only property that is set during the Camera preRender method every frame. It is true if the Camera is set to render round pixels and the zoom values are integers, otherwise it is false. This is then fed into the MultiPipeline when rendering sprites and textures.

Bug Fixes

  • The Canvas Renderer and WebGL Multi Pipeline now uses the new renderRoundPixels boolean to determine if it can render a Sprite or a Texture with rounded position values, or not. This fixes an issue where black lines would appear between tightly grouped sprites or tiles at non-integer Camera zoom values. Fix #6907 (thanks @MarcJamesIO)
  • RenderTarget.resize will now check the autoResize property before applying the change. Textures that have been locked to a fixed size, such as FX POT buffers, will no longer be resized to the full canvas dimensions, causing Out of Memory errors on some mobile devices. Fix #6914 (thanks @mikaleerhart @DavidTalevski)
  • The Array.MoveAbove function didn't recalculate the baseIndex after the splice, meaning the item would end up in the wrong location.
  • The HexagonalTileToWorldXY function incorrectly used this instead of layer causing it to error in hex tilemaps with x axis staggering. Fix #6913 (thanks @jummy123)
  • The Text Game Object could truncate the length of the Text when setLetterSpacing was used. Fix #6915 (thanks @monteiz @rexrainbow)
  • The EXPAND Scale Mode would cause the error "Framebuffer status: Incomplete Attachment" under WebGL if the Phaser game loaded into an iframe or element with a size of 0 on either axis, such as when you load the game into a 0x0 iframe before expanding it. It now protects against divide by zero errors.
  • The RenderTarget.willResize method will now check if the values given to it are actually numbers. If not it will return false.

Examples, Documentation, Beta Testing and TypeScript

Thanks to the following for helping with the Phaser Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@thompson318

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v3.85.2

Updates

  • WebGLRenderer.setExtensions is a new method that queries the GL context to get the list of supported extensions. Which it then sets into the class properties. This method is called internally as part of the init and restore process.

Bug Fixes

  • When the WebGL context was restored it would incorrectly try to call init.setupExtensions() which didn't exist. It now calls the correct method, WebGLRenderer.setExtensions. Fix #6905 (thanks @RedRoosterMobile)
  • TransformMatrix.setQuad has been fixed so it no longer rounds the quad dimensions, only the x/y coordinates. This fixes a bug where it could give slightly different (+- 1px) sized textures based on how the dimensions were rounded when using roundPixels on the camera. Fix #6874 (thanks @saintflow47)

Examples, Documentation, Beta Testing and TypeScript

Thanks to the following for helping with the Phaser Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@AlvaroNeuronup

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v3.85.1

Version 3.85.1 - Itsuki - 5th September 2024

MatterJS

  • MatterJS has been updated to version 0.20.0 - Here are all the details about this update.
  • A new wrap method has been natively integrated into the Body class to replace the existing MatterWrap plugin. Here's how it works.
  • The Matter attractors plugin has been natively integrated into the Body class and Matter engine. More details here.
  • Integrated MatterCollisionEvents plugin functionality directly into the Matter.World class to handle collisions more effectively. More details here.
  • Updated Matter.World to improve the performance, accuracy, and reliability of the update method in handling physics simulations or animations. More details here.
  • Fixed Matter.World bug where group.length returns undefined. Changed to group.getLength() to correctly return number of children in a group.
  • Calling Matter.World.pause would stop the world updating, but the Runner timeLastTick wasn't reset when resume was called, causing all the bodies to advance. The time is now reset correctly. Fix #6892 (thanks @philipgriffin)

Round Pixels

Includes a Potentially Breaking Change

The way roundPixels has been handled in this release has been changed significantly. In previous versions we passed a uniform to the shaders and handled the pixel rounding on the GPU. However, this caused issues with our batching flow - for example, a Sprite would need to be rounded, but a Text or Shape object would not. This lead to complications in some parts of the render code.

In this release we have removed the shader uniform and branching and also made roundPixels default to false in the Game Config. Previously, it was true, so you may need to switch this flag if you were relying on it. Here are the results of this change:

  • The Game Config roundPixels property now defaults to false.
  • The uRoundPixels uniform has been removed from the Single, Multi and Mobile vertex shaders.
  • Setting the uRoundPixels uniform has been removed from the Single, Rope, PreFX, PostFX, Multi and Mobile WebGL Pipelines.
  • The Multi Pipeline and Blitter WebGL Renderer will now pass the camera.roundPixels value to the Transform Matrix setQuad method.
  • The Multi Pipeline batchSprite and batchTexture methods will now apply Math.floor to the sprite matrix calculations if camera round pixels is enabled.
  • BaseCamera.preRender has been removed. This method was completely overridden by Camera.preRender which is the method that contained the correct rendering logic. As the Base Camera variant was not used internally outside of Dynamic Textures, we have removed it to save space.
  • Camera.preRender has been updated to use both zoomX and zoomY for the matrix transform.
  • Camera.preRender has been updated to apply Math.floor to the scroll factor when rounding is enabled on the Camera. This fixes an issue where following sprites with Camera lerp, or heavy zoom factors, would cause 'stuttering' at sub-pixel values.

New Features - Loader

The Loader now has a new feature called maxRetries. This specifies the number of times a single File will retry loading itself should it error for whatever reason, such as poor network connectivity. The default value is 2. You can change this in the Game Config, on the LoaderPlugin instance, on the FileConfig or on the File level itself. Thanks to @pavle-goloskokovic for the suggestion.

  • loader.maxRetries is a new Game Config option to set the number of retries a file will attempt to load. The default is 2.
  • LoaderPlugin.maxRetries is a new property that holds the number of times to retry loading a single file before it fails. This property is set via the Game Config, but can also be adjusted manually. Changing it doesn't not impact files already in the load queue, only those added later.
  • FileConfig.maxRetries is a new File Config option to set the number of retries a file will attempt to load. If not specified in the config, the value is read from the LoaderPlugin.maxRetries property.
  • Loader.File.retryAttempts is the internal property holding the counter for the number of times to retry loading this file before it fails. This value is decreased after each attempt. When it reaches zero, the file is considered as failed.

New Features

  • BaseSoundManager.isPlaying is a new method that will return a boolean if the given sound key is playing. If you don't provide a key, it will return a boolean if any sound is playing (thanks @samme)
  • WebGLRenderer.dispatchContextLost is a new internal method that 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, be sure to invoke this method in due course.
  • WebGLRenderer.dispatchContextRestore is a new internal method that is called when the WebGL context is restored. By default this is bound to the property WebGLRenderer.contextRestoreHandler. If you override the context restore handler, be sure to invoke this method in due course.
  • WebGLRenderer.setContextHandlers is a new internal method with 2 optional parameters: contextLost and contextRestored. These allow you to overwrite the default contextLostHandler and contextRestoreHandler handlers. (thanks @yaustar)
  • Phaser.Textures.Frame#setCutPosition is a new internal method with 2 optional parameters: x and y. These sets the x and y position within the source image to cut from.
  • Phaser.Textures.Frame#setCutSize is a new internal method with 2 parameters: width and height. These sets the width, and height of the area in the source image to cut. (thanks @FelipeIzolan)
  • Introduced new constants in ORIENTATION_CONST. The constants LANDSCAPE_SECONDARY and PORTRAIT_SECONDARY have been added to the Phaser.Scale.Orientation object. These constants represent the secondary landscape and portrait orientations respectively. This addition provides more granular control over device orientation handling in Phaser. Fix #6837 (thanks @rexrainbow)
  • Introduced updateConfig method in ParticleEmitter to allow dynamic updating of Particle Emitter configurations. This method enables existing properties to be overridden and new properties to be added to the emitter's configuration. It ensures that the emitter is reset with the updated configuration for more flexible particle effects management.
  • Added functionality to the Phaser.Textures.DynamicTexture#clear method. Clear a specific area within a Dynamic Texture by specifying x, y, width, and height parameters to clear only a portion of the texture. Fix #6853 (thanks @SelfDevTV)
  • Added functionality to the Phaser.Renderer.WebGL.RenderTarget#clear method. Clear a specific area within the RenderTarget by specifying x, y, width, and height parameters.
  • Added Default Image Handling in TextureManager. In the game config, set defaultImage to null to ignore loading the defaultImage.
  • Added Missing Image Handling in TextureManager. In the game config, set missingImage to null to ignore loading the missingImage.
  • Added White Image Support in TextureManager. In the game config, set whiteImage to null to ignore loading the whiteImage.
  • Phaser.Core.TimeStep#pauseDuration is a new property that holds the duration of the most recent game pause, if any, in ms (thanks @samme)
  • The Game Events#RESUME event now contains a new parameter pauseDuration which is the duration, in ms, that the game was paused for (thanks @samme)
  • Added Phaser.Loader.LoaderPlugin#removePack method to LoaderPlugin that removes resources listed in an Asset Pack.(thanks @samme)
  • When using Scene.switch you can now optionally specify a data argument, just like with Scene start, which will be passed along to the Scene that was switched to (thanks @wooseok123)
  • PRE_RENDER_CLEAR is a new event dispatched by the WebGL and Canvas Renderer. It's dispatched at the start of the render step, immediately before the canvas is cleared. This allows you to toggle the clearBeforeRender property as required, to have fine-grained control over when the canvas is cleared during render.
  • Video.getFirstFrame is a new method that can be used to load the first frame of the Video into its texture without starting playback. This is useful if you want to display the first frame of a video behind a 'Play' button, without calling the 'play' method.
  • GameObject.getDisplayList is a new method that will return the underlying list object that the Game Object belongs to, either the display list or its parent container.
  • GameObject.setToTop is a new method that will move the Game Object to the top of the display list, or its parent container (thanks @rexrainbow)
  • GameObject.setToBack is a new method that will move the Game Object to the bottom of the display list, or its parent container (thanks @rexrainbow)
  • GameObject.setAbove is a new method that will move the Game Object to appear above a given Game Object (thanks @rexrainbow)
  • GameObject.setBelow is a new method that will move the Game Object to appear below a given Game Object (thanks @rexrainbow)

WebGL Rendering Updates

  • WebGLTextureWrapper.update expanded:
    • source parameter is now type ?object, so it can be used for anything that is valid in the constructor.
    • New format parameter can update the texture format.

Updates - Input System

  • The GameObject.disableInteractive method has a new optional parameter resetCursor. If set, this will reset the current custom input cursor - regardless if the Game Object was the one that set it, or not.
  • The GameObject.removeInteractive method has a new optional parameter resetCursor. If set, this will reset the current custom input cursor - regardless if the Game Object was the one that set it, or not.
  • The InputManager.resetCursor method has a new optional boolean forceReset which will reset the state of the CSS canvas cursor, regardless if there is a given Interactive Object, or not.
  • The InputPlugin.isActive method will now check if the InputPlugin has the InputManager reference set, and if that is also enabled, as well as checking its own enabled state and that of the Scene.
  • InputPlugin.resetCursor is a new method that will reset a custom CSS cursor from the main canvas, regardless of the interactive state of any Game Objects.
  • The InputPlugin.disable method has a new optional boolean parameter resetCursor which will reset the CSS custom cursor if true.
  • InputPlugin.setCursor is a new method that will immediately set the CSS cursor to the given Interactive Objects cursor. Previously, this was hidden behind a private method in the Input Manager.

All of the core Input Plugin process methods have been rewritten. The methods that have changed are:

  • InputPlugin.processMoveEvents
  • InputPlugin.processWheelEvent
  • InputPlugin.processOverEvents
  • InputPlugin.processOutEvents
  • InputPlugin.processOverOutEvents
  • InputPlugin.processUpEvents
  • InputPlugin.processDownEvents

And they all now do the following flow:

1) They will now iterate over the array of objects to be inspected. If the object doesn't have an input handler, or their handler has been disabled, they are skipped for event consideration. 2) If they have an input handler, the Game Object specific event is dispatched (i.e. sprite.on('pointerdown')) 3) The result of this call is checked. If the Event has been cancelled, or if the Input Plugin now returns isActive() false then it will break from the handler loop. This will only happen if the user explicitly tells the event to stop propogation, or if they disable either the Input Plugin, or the entire Input Manager, during the event handler. Previously, only the state of cancelled event was checked. Also previously, if the Game Objects own input handler was removed or disabled as a result of their event handler, it would break from the process loop. This no longer happens. It will carry on inspecting the remaining interactive objects in the loop, as long as the Input system itself wasn't disabled. 4) After this, the Game Object is checked to see if it is still input enabled. If it is, the Scene level events, like this.input.on('gameobjectdown') are emitted. 5) The results of this call are also checked. Again, if the Event has been cancelled, or if the Input Plugin now returns isActive() false then it will break from the handler loop, otherwise it carries on. 6) After the loop is complete it does one final check to see if the Event was cancelled, or if the Input Plugin is no longer active. If both of those pass, it emits the final event from the Input Plugin itself (i.e. this.input.on('pointerdown') from a Scene)

The above flow is new in v3.85 and will catch a lot more strange edge-cases, where Game Objects, or the Event, or the whole Input system is disabled during an active event handler. The above fixes #6833 (thanks @ddanushkin), #6766 (thanks @pabloNeuronup) and #6754 (thanks @orcomarcio)

  • InputPlugin.forceDownState is a new method that will force the given Game Object into the 'down' input state, regardless of what state it is currently in. This will emit the relevant events accordingly.
  • InputPlugin.forceUpState is a new method that will force the given Game Object into the 'up' input state, regardless of what state it is currently in. This will emit the relevant events accordingly.
  • InputPlugin.forceOverState is a new method that will force the given Game Object into the 'over' input state, regardless of what state it is currently in. This will emit the relevant events accordingly.
  • InputPlugin.forceOutState is a new method that will force the given Game Object into the 'out' input state, regardless of what state it is currently in. This will emit the relevant events accordingly.
  • InputPlugin.forceState is a new internal method that forces a Game Object into the given state.

Updates

  • Added Phaser.Scale.ScaleManager.leaveFullScreenSuccessHandler method to separate Events.LEAVE_FULLSCREEN from Phaser.Scale.ScaleManager.stopFullscreen to ensure Events.LEAVE_FULLSCREEN is only emitted once when exiting fullscreen mode. (Fix #6885, thanks @Antriel)
  • Calling Timeline.pause will now pause any currently active Tweens that the Timeline had started (thanks @monteiz)
  • Calling Timeline.resume will now resume any currently paused Tweens that the Timeline had started (thanks @monteiz)
  • Calling Timeline.clear and Timeline.destroy will now destroy any currently active Tweens that the Timeline had created. Previously, active tweens would continue to play to completion (thanks @monteiz)
  • TimelineEvent has a new property called tweenInstance. If the Timeline event has a tween that has been activated, this will hold a reference to it.
  • If you create a BitmapText with an invalid key it will now throw a runtime error. Previously it just issued a console warning and then crashed (thanks @samme)
  • The console warnings when Audio files are missing/incorrect have been improved (thanks @samme)
  • The requestVideoFrame polyfill has been updated to the latest release, which should resolve some SSR framework issues. Fix #6776 (thanks @lantictac)
  • ScaleManager listeners includes checks for the screen.orientation object and adds/removes a change eventListener method to handle screen orientation changes on mobile devices. The orientationchange event is still maintained for backwards compatibility. Fix #6837 (thanks @rexrainbow)
  • When creating a new TileSprite, setting either width or height to 0 results in both values being set to the displayFrame.width and displayFrame.height. The updated logic now checks for width and height separately. If width is 0, it is set to displayFrame.width. If height is 0, it is set to displayFrame.height. Fix #6857 (thanks @GaryStanton)
  • Updated GetBitmapTextSize with improved maxWidth calculations for wrapped text.
  • Vector3.subVectors is a new method that will take 2 Vector3s, subtract them from each other and store the result in the Vector3 it was called on.
  • The TextStyle.setStyle method will no longer mutate the given style object if it includes a numeric fontSize value. Fix #6863 (thanks @stormpanda)
  • Calling the Shape.Ellipse.setSize method will internally call updateDisplayOrigin to retain position after a size change.
  • The BitmapText BatchChar function now inlines all of the matrix math, avoiding 16 function calls per character rendered.

Bug Fixes

  • The activePointers game config option is now the correct amount of touch input pointers set. Fix #6783 (thanks @samme)
  • The method TextureManager.checkKey will now return false if the key is not a string, which fixes issues where a texture could be created if a key was given that was already in use (thanks Will Macfarlane).
  • Added all of the missing Loader Config values (such as imageLoadType) to LoaderConfig, so they now appear in the TypeScript defs.
  • The EXPAND scale mode had a bug that prevented it from using the world bounds cameras, cutting rendering short. Fix #6767 (thanks @Calcue-dev @rexrainbow)
  • Calling getPipelineName() on a Game Object would cause a runtime error if running under Canvas. It now simply returns null. Fix #6799 (thanks @samme)
  • Calling the Arcade Body setPushable(false) method for circle bodies prevents the bodies from being pushed. Fix #5617 (thanks @kainage)
  • Calling addDeathZone() on a particle emitter Game Object had a bug where the DeathZone used world position coordinates. DeathZone now uses local position coordinates following the particle emitter position. Fix #6371 (thanks @vforsh)
  • Updated the GetLineToLine method in GetLineToLine to handle the case where dx1 or dy1 values is zero. This ensures the function correctly returns null in this case to prevent errors in calculations involving line segments. Fix #6579 (thanks @finscn)
  • Resolved all kerning issues in WebGL bitmap text rendering. This includes adjustments to glyph positioning and spacing, ensuring accurate and visually pleasing text display across all WebGL contexts. Fix #6631 (thanks @monteiz)
  • Fixed Group vs Group collisions failing when performing a bitwise & operation between body1.collisionMask and body2.collisionCategory. The default collisionMask value is changed to 2147483647 to correctly match any collisionCategory. Fix #6764 (thanks @codeimpossible)
  • Resolved an issue in BitmapText where adding a space character ' ' at the end of a line did not correctly align the vertical position of the new line. The updated calculation now correctly accounts for both line height and line spacing. Fix #6717 (thanks @wooseok123)
  • Resolved an issue in BitmapText where an extra empty line was added when setMaxWidth was called, and the width of the line was less than a word. Previously, yAdvance was incorrectly incremented by lineHeight + lineSpacing for each word, leading to an unintended increase in vertical space. The correction now calculates yAdvance based on the currentLine index, ensuring that vertical spacing accurately reflects the number of lines. Fix #6807 (thanks @AlvaroNeuronup)
  • Resolved an issue in BitmapText where adding a space character ' ' at the end of a line caused the following line of to ignore line wrapping when using setMaxWidth. Fix #6860 (thanks @bagyoni)
  • The Matrix4.lookAtRH method would fail because it called two missing Vector3 methods.
  • The RenderTarget will now automatically listen for the Renderer resize event if autoResize is true. This fixes an issue with Bitmap Masks where they wouldn't resize if the renderer resized. Fix #6769 #6794 (thanks @pavels @seansps)
  • The Texture.getFrameBounds method will now include the BASE texture in its calculations. This prevents it from returning a size of Infinity. This fixes an issue where a Tileset with margin/spacing loaded via load.spritesheet instead of load.image would have its margin and spacing ignored. Fix #6823 (thanks @damian-pastorini)
  • If you used letter spacing on a Text Game Object, combined with stroke, the stroke would be mis-aligned. The stroke is now applied to the letter-spaced text as well (thanks @RomanFrom710)
  • The PreFXPipeline.batchQuad method will now apply Math.round to the target bounds center point. This prevents sub-pixel values during the copyTextSubImage2D call, preventing sprites with pre-fx from appearing mis-aligned during camera pans. Fix #6879 (thanks @Antriel)
  • If you had a sprite on the display list using the LightPipeline, followed by a Mesh using the LightPipeline, and you invalidated the mesh (i.e. by rotating it), it would cause a runtime error in the current batch. Fix #6822 (thanks @urueda)
  • The Arcade Physics processCallback will now correctly handle non-Game Object physics bodies and pass them to the callback (thanks @ospira)
  • If you set a WebAudioSound to loop and set SoundManager.pauseOnBlur = false, then if you start the sound and tab away from Phaser, the sound wouldn't then loop on return to the game, if the loop expired while the tab was out of focus. This was due to checking the audio source node target against the wrong internal property. Fix #6702 (thanks @michalfialadev)
  • The Mesh WebGLRenderer will now recalculate the vertexOffset correctly if the batch flushes, fixing an issue where it would display missing triangles in a mesh after a batch flush. Fix #6814 (thanks @pavels)
  • The NineSlice Game Object will now guard against an invalid texture by checking for the frame and textureFrame vars before trying to read values from them. Fix #6804 (thanks @IvanDem)
  • DOM Game Elements are now kept in the correct position when a Scene camera zooms out. Previously, they only worked if you kept their origin at 0x0, or didn't zoom the camera out. Fix #6817 #6607 (thanks @moufmouf)

Input Bug Fixes

  • The method pointer.leftButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.rightButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.middleButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.backButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.forwardButtonReleased will now return true when multiple mouse buttons are being pressed. Fix #6027 (thanks @michalfialadev)

Examples, Documentation, Beta Testing and TypeScript

Thanks to the following for helping with the Phaser Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@AlbertMontagutCasero @Andrek25 @Antriel @leha-games @lgtome @monteiz @rexrainbow @saintflow47 @samme @ssotangkur @vankop

Deprecation Warning for the next release

The next release of Phaser will make the following API-breaking changes:

  • We are removing Phaser.Struct.Map and replacing it with a regular JS Map instance. This means methods like contains and setAll will be gone.
  • We are removing Phaser.Struct.Set and replacing it with a regular JS Set instance. This means methods like iterateLocal will be gone.
  • The Create.GenerateTexture, all of the Create Palettes and the create folder will be removed.
  • The phaser-ie9.js entry-point will be removed along with all associated polyfills.
  • The Spine 3 and Spine 4 plugins will no longer be updated. You should now use the official Phaser Spine plugin created by Esoteric Software.
  • The Geom.Point class and all related functions will be removed. All functionality for this can be found in the existing Vector2 math classes. All Geometry classes that currently create and return Point objects will be updated to return Vector2 objects instead.
  • We will be moving away from Webpack and using ESBuild to build the next version of Phaser.

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v3.85.0

Version 3.85.0 - Itsuki - 5th September 2024

MatterJS

  • MatterJS has been updated to version 0.20.0 - Here are all the details about this update.
  • A new wrap method has been natively integrated into the Body class to replace the existing MatterWrap plugin. Here's how it works.
  • The Matter attractors plugin has been natively integrated into the Body class and Matter engine. More details here.
  • Integrated MatterCollisionEvents plugin functionality directly into the Matter.World class to handle collisions more effectively. More details here.
  • Updated Matter.World to improve the performance, accuracy, and reliability of the update method in handling physics simulations or animations. More details here.
  • Fixed Matter.World bug where group.length returns undefined. Changed to group.getLength() to correctly return number of children in a group.
  • Calling Matter.World.pause would stop the world updating, but the Runner timeLastTick wasn't reset when resume was called, causing all the bodies to advance. The time is now reset correctly. Fix #6892 (thanks @philipgriffin)

Round Pixels

Includes a Potentially Breaking Change

The way roundPixels has been handled in this release has been changed significantly. In previous versions we passed a uniform to the shaders and handled the pixel rounding on the GPU. However, this caused issues with our batching flow - for example, a Sprite would need to be rounded, but a Text or Shape object would not. This lead to complications in some parts of the render code.

In this release we have removed the shader uniform and branching and also made roundPixels default to false in the Game Config. Previously, it was true, so you may need to switch this flag if you were relying on it. Here are the results of this change:

  • The Game Config roundPixels property now defaults to false.
  • The uRoundPixels uniform has been removed from the Single, Multi and Mobile vertex shaders.
  • Setting the uRoundPixels uniform has been removed from the Single, Rope, PreFX, PostFX, Multi and Mobile WebGL Pipelines.
  • The Multi Pipeline and Blitter WebGL Renderer will now pass the camera.roundPixels value to the Transform Matrix setQuad method.
  • The Multi Pipeline batchSprite and batchTexture methods will now apply Math.floor to the sprite matrix calculations if camera round pixels is enabled.
  • BaseCamera.preRender has been removed. This method was completely overridden by Camera.preRender which is the method that contained the correct rendering logic. As the Base Camera variant was not used internally outside of Dynamic Textures, we have removed it to save space.
  • Camera.preRender has been updated to use both zoomX and zoomY for the matrix transform.
  • Camera.preRender has been updated to apply Math.floor to the scroll factor when rounding is enabled on the Camera. This fixes an issue where following sprites with Camera lerp, or heavy zoom factors, would cause 'stuttering' at sub-pixel values.

New Features - Loader

The Loader now has a new feature called maxRetries. This specifies the number of times a single File will retry loading itself should it error for whatever reason, such as poor network connectivity. The default value is 2. You can change this in the Game Config, on the LoaderPlugin instance, on the FileConfig or on the File level itself. Thanks to @pavle-goloskokovic for the suggestion.

  • loader.maxRetries is a new Game Config option to set the number of retries a file will attempt to load. The default is 2.
  • LoaderPlugin.maxRetries is a new property that holds the number of times to retry loading a single file before it fails. This property is set via the Game Config, but can also be adjusted manually. Changing it doesn't not impact files already in the load queue, only those added later.
  • FileConfig.maxRetries is a new File Config option to set the number of retries a file will attempt to load. If not specified in the config, the value is read from the LoaderPlugin.maxRetries property.
  • Loader.File.retryAttempts is the internal property holding the counter for the number of times to retry loading this file before it fails. This value is decreased after each attempt. When it reaches zero, the file is considered as failed.

New Features

  • BaseSoundManager.isPlaying is a new method that will return a boolean if the given sound key is playing. If you don't provide a key, it will return a boolean if any sound is playing (thanks @samme)
  • WebGLRenderer.dispatchContextLost is a new internal method that 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, be sure to invoke this method in due course.
  • WebGLRenderer.dispatchContextRestore is a new internal method that is called when the WebGL context is restored. By default this is bound to the property WebGLRenderer.contextRestoreHandler. If you override the context restore handler, be sure to invoke this method in due course.
  • WebGLRenderer.setContextHandlers is a new internal method with 2 optional parameters: contextLost and contextRestored. These allow you to overwrite the default contextLostHandler and contextRestoreHandler handlers. (thanks @yaustar)
  • Phaser.Textures.Frame#setCutPosition is a new internal method with 2 optional parameters: x and y. These sets the x and y position within the source image to cut from.
  • Phaser.Textures.Frame#setCutSize is a new internal method with 2 parameters: width and height. These sets the width, and height of the area in the source image to cut. (thanks @FelipeIzolan)
  • Introduced new constants in ORIENTATION_CONST. The constants LANDSCAPE_SECONDARY and PORTRAIT_SECONDARY have been added to the Phaser.Scale.Orientation object. These constants represent the secondary landscape and portrait orientations respectively. This addition provides more granular control over device orientation handling in Phaser. Fix #6837 (thanks @rexrainbow)
  • Introduced updateConfig method in ParticleEmitter to allow dynamic updating of Particle Emitter configurations. This method enables existing properties to be overridden and new properties to be added to the emitter's configuration. It ensures that the emitter is reset with the updated configuration for more flexible particle effects management.
  • Added functionality to the Phaser.Textures.DynamicTexture#clear method. Clear a specific area within a Dynamic Texture by specifying x, y, width, and height parameters to clear only a portion of the texture. Fix #6853 (thanks @SelfDevTV)
  • Added functionality to the Phaser.Renderer.WebGL.RenderTarget#clear method. Clear a specific area within the RenderTarget by specifying x, y, width, and height parameters.
  • Added Default Image Handling in TextureManager. In the game config, set defaultImage to null to ignore loading the defaultImage.
  • Added Missing Image Handling in TextureManager. In the game config, set missingImage to null to ignore loading the missingImage.
  • Added White Image Support in TextureManager. In the game config, set whiteImage to null to ignore loading the whiteImage.
  • Phaser.Core.TimeStep#pauseDuration is a new property that holds the duration of the most recent game pause, if any, in ms (thanks @samme)
  • The Game Events#RESUME event now contains a new parameter pauseDuration which is the duration, in ms, that the game was paused for (thanks @samme)
  • Added Phaser.Loader.LoaderPlugin#removePack method to LoaderPlugin that removes resources listed in an Asset Pack.(thanks @samme)
  • When using Scene.switch you can now optionally specify a data argument, just like with Scene start, which will be passed along to the Scene that was switched to (thanks @wooseok123)
  • PRE_RENDER_CLEAR is a new event dispatched by the WebGL and Canvas Renderer. It's dispatched at the start of the render step, immediately before the canvas is cleared. This allows you to toggle the clearBeforeRender property as required, to have fine-grained control over when the canvas is cleared during render.
  • Video.getFirstFrame is a new method that can be used to load the first frame of the Video into its texture without starting playback. This is useful if you want to display the first frame of a video behind a 'Play' button, without calling the 'play' method.
  • GameObject.getDisplayList is a new method that will return the underlying list object that the Game Object belongs to, either the display list or its parent container.
  • GameObject.setToTop is a new method that will move the Game Object to the top of the display list, or its parent container (thanks @rexrainbow)
  • GameObject.setToBack is a new method that will move the Game Object to the bottom of the display list, or its parent container (thanks @rexrainbow)
  • GameObject.setAbove is a new method that will move the Game Object to appear above a given Game Object (thanks @rexrainbow)
  • GameObject.setBelow is a new method that will move the Game Object to appear below a given Game Object (thanks @rexrainbow)

WebGL Rendering Updates

  • WebGLTextureWrapper.update expanded:
    • source parameter is now type ?object, so it can be used for anything that is valid in the constructor.
    • New format parameter can update the texture format.

Updates - Input System

  • The GameObject.disableInteractive method has a new optional parameter resetCursor. If set, this will reset the current custom input cursor - regardless if the Game Object was the one that set it, or not.
  • The GameObject.removeInteractive method has a new optional parameter resetCursor. If set, this will reset the current custom input cursor - regardless if the Game Object was the one that set it, or not.
  • The InputManager.resetCursor method has a new optional boolean forceReset which will reset the state of the CSS canvas cursor, regardless if there is a given Interactive Object, or not.
  • The InputPlugin.isActive method will now check if the InputPlugin has the InputManager reference set, and if that is also enabled, as well as checking its own enabled state and that of the Scene.
  • InputPlugin.resetCursor is a new method that will reset a custom CSS cursor from the main canvas, regardless of the interactive state of any Game Objects.
  • The InputPlugin.disable method has a new optional boolean parameter resetCursor which will reset the CSS custom cursor if true.
  • InputPlugin.setCursor is a new method that will immediately set the CSS cursor to the given Interactive Objects cursor. Previously, this was hidden behind a private method in the Input Manager.

All of the core Input Plugin process methods have been rewritten. The methods that have changed are:

  • InputPlugin.processMoveEvents
  • InputPlugin.processWheelEvent
  • InputPlugin.processOverEvents
  • InputPlugin.processOutEvents
  • InputPlugin.processOverOutEvents
  • InputPlugin.processUpEvents
  • InputPlugin.processDownEvents

And they all now do the following flow:

1) They will now iterate over the array of objects to be inspected. If the object doesn't have an input handler, or their handler has been disabled, they are skipped for event consideration. 2) If they have an input handler, the Game Object specific event is dispatched (i.e. sprite.on('pointerdown')) 3) The result of this call is checked. If the Event has been cancelled, or if the Input Plugin now returns isActive() false then it will break from the handler loop. This will only happen if the user explicitly tells the event to stop propogation, or if they disable either the Input Plugin, or the entire Input Manager, during the event handler. Previously, only the state of cancelled event was checked. Also previously, if the Game Objects own input handler was removed or disabled as a result of their event handler, it would break from the process loop. This no longer happens. It will carry on inspecting the remaining interactive objects in the loop, as long as the Input system itself wasn't disabled. 4) After this, the Game Object is checked to see if it is still input enabled. If it is, the Scene level events, like this.input.on('gameobjectdown') are emitted. 5) The results of this call are also checked. Again, if the Event has been cancelled, or if the Input Plugin now returns isActive() false then it will break from the handler loop, otherwise it carries on. 6) After the loop is complete it does one final check to see if the Event was cancelled, or if the Input Plugin is no longer active. If both of those pass, it emits the final event from the Input Plugin itself (i.e. this.input.on('pointerdown') from a Scene)

The above flow is new in v3.85 and will catch a lot more strange edge-cases, where Game Objects, or the Event, or the whole Input system is disabled during an active event handler. The above fixes #6833 (thanks @ddanushkin), #6766 (thanks @pabloNeuronup) and #6754 (thanks @orcomarcio)

  • InputPlugin.forceDownState is a new method that will force the given Game Object into the 'down' input state, regardless of what state it is currently in. This will emit the relevant events accordingly.
  • InputPlugin.forceUpState is a new method that will force the given Game Object into the 'up' input state, regardless of what state it is currently in. This will emit the relevant events accordingly.
  • InputPlugin.forceOverState is a new method that will force the given Game Object into the 'over' input state, regardless of what state it is currently in. This will emit the relevant events accordingly.
  • InputPlugin.forceOutState is a new method that will force the given Game Object into the 'out' input state, regardless of what state it is currently in. This will emit the relevant events accordingly.
  • InputPlugin.forceState is a new internal method that forces a Game Object into the given state.

Updates

  • Added Phaser.Scale.ScaleManager.leaveFullScreenSuccessHandler method to separate Events.LEAVE_FULLSCREEN from Phaser.Scale.ScaleManager.stopFullscreen to ensure Events.LEAVE_FULLSCREEN is only emitted once when exiting fullscreen mode. (Fix #6885, thanks @Antriel)
  • Calling Timeline.pause will now pause any currently active Tweens that the Timeline had started (thanks @monteiz)
  • Calling Timeline.resume will now resume any currently paused Tweens that the Timeline had started (thanks @monteiz)
  • Calling Timeline.clear and Timeline.destroy will now destroy any currently active Tweens that the Timeline had created. Previously, active tweens would continue to play to completion (thanks @monteiz)
  • TimelineEvent has a new property called tweenInstance. If the Timeline event has a tween that has been activated, this will hold a reference to it.
  • If you create a BitmapText with an invalid key it will now throw a runtime error. Previously it just issued a console warning and then crashed (thanks @samme)
  • The console warnings when Audio files are missing/incorrect have been improved (thanks @samme)
  • The requestVideoFrame polyfill has been updated to the latest release, which should resolve some SSR framework issues. Fix #6776 (thanks @lantictac)
  • ScaleManager listeners includes checks for the screen.orientation object and adds/removes a change eventListener method to handle screen orientation changes on mobile devices. The orientationchange event is still maintained for backwards compatibility. Fix #6837 (thanks @rexrainbow)
  • When creating a new TileSprite, setting either width or height to 0 results in both values being set to the displayFrame.width and displayFrame.height. The updated logic now checks for width and height separately. If width is 0, it is set to displayFrame.width. If height is 0, it is set to displayFrame.height. Fix #6857 (thanks @GaryStanton)
  • Updated GetBitmapTextSize with improved maxWidth calculations for wrapped text.
  • Vector3.subVectors is a new method that will take 2 Vector3s, subtract them from each other and store the result in the Vector3 it was called on.
  • The TextStyle.setStyle method will no longer mutate the given style object if it includes a numeric fontSize value. Fix #6863 (thanks @stormpanda)
  • Calling the Shape.Ellipse.setSize method will internally call updateDisplayOrigin to retain position after a size change.
  • The BitmapText BatchChar function now inlines all of the matrix math, avoiding 16 function calls per character rendered.

Bug Fixes

  • The activePointers game config option is now the correct amount of touch input pointers set. Fix #6783 (thanks @samme)
  • The method TextureManager.checkKey will now return false if the key is not a string, which fixes issues where a texture could be created if a key was given that was already in use (thanks Will Macfarlane).
  • Added all of the missing Loader Config values (such as imageLoadType) to LoaderConfig, so they now appear in the TypeScript defs.
  • The EXPAND scale mode had a bug that prevented it from using the world bounds cameras, cutting rendering short. Fix #6767 (thanks @Calcue-dev @rexrainbow)
  • Calling getPipelineName() on a Game Object would cause a runtime error if running under Canvas. It now simply returns null. Fix #6799 (thanks @samme)
  • Calling the Arcade Body setPushable(false) method for circle bodies prevents the bodies from being pushed. Fix #5617 (thanks @kainage)
  • Calling addDeathZone() on a particle emitter Game Object had a bug where the DeathZone used world position coordinates. DeathZone now uses local position coordinates following the particle emitter position. Fix #6371 (thanks @vforsh)
  • Updated the GetLineToLine method in GetLineToLine to handle the case where dx1 or dy1 values is zero. This ensures the function correctly returns null in this case to prevent errors in calculations involving line segments. Fix #6579 (thanks @finscn)
  • Resolved all kerning issues in WebGL bitmap text rendering. This includes adjustments to glyph positioning and spacing, ensuring accurate and visually pleasing text display across all WebGL contexts. Fix #6631 (thanks @monteiz)
  • Fixed Group vs Group collisions failing when performing a bitwise & operation between body1.collisionMask and body2.collisionCategory. The default collisionMask value is changed to 2147483647 to correctly match any collisionCategory. Fix #6764 (thanks @codeimpossible)
  • Resolved an issue in BitmapText where adding a space character ' ' at the end of a line did not correctly align the vertical position of the new line. The updated calculation now correctly accounts for both line height and line spacing. Fix #6717 (thanks @wooseok123)
  • Resolved an issue in BitmapText where an extra empty line was added when setMaxWidth was called, and the width of the line was less than a word. Previously, yAdvance was incorrectly incremented by lineHeight + lineSpacing for each word, leading to an unintended increase in vertical space. The correction now calculates yAdvance based on the currentLine index, ensuring that vertical spacing accurately reflects the number of lines. Fix #6807 (thanks @AlvaroNeuronup)
  • Resolved an issue in BitmapText where adding a space character ' ' at the end of a line caused the following line of to ignore line wrapping when using setMaxWidth. Fix #6860 (thanks @bagyoni)
  • The Matrix4.lookAtRH method would fail because it called two missing Vector3 methods.
  • The RenderTarget will now automatically listen for the Renderer resize event if autoResize is true. This fixes an issue with Bitmap Masks where they wouldn't resize if the renderer resized. Fix #6769 #6794 (thanks @pavels @seansps)
  • The Texture.getFrameBounds method will now include the BASE texture in its calculations. This prevents it from returning a size of Infinity. This fixes an issue where a Tileset with margin/spacing loaded via load.spritesheet instead of load.image would have its margin and spacing ignored. Fix #6823 (thanks @damian-pastorini)
  • If you used letter spacing on a Text Game Object, combined with stroke, the stroke would be mis-aligned. The stroke is now applied to the letter-spaced text as well (thanks @RomanFrom710)
  • The PreFXPipeline.batchQuad method will now apply Math.round to the target bounds center point. This prevents sub-pixel values during the copyTextSubImage2D call, preventing sprites with pre-fx from appearing mis-aligned during camera pans. Fix #6879 (thanks @Antriel)
  • If you had a sprite on the display list using the LightPipeline, followed by a Mesh using the LightPipeline, and you invalidated the mesh (i.e. by rotating it), it would cause a runtime error in the current batch. Fix #6822 (thanks @urueda)
  • The Arcade Physics processCallback will now correctly handle non-Game Object physics bodies and pass them to the callback (thanks @ospira)
  • If you set a WebAudioSound to loop and set SoundManager.pauseOnBlur = false, then if you start the sound and tab away from Phaser, the sound wouldn't then loop on return to the game, if the loop expired while the tab was out of focus. This was due to checking the audio source node target against the wrong internal property. Fix #6702 (thanks @michalfialadev)
  • The Mesh WebGLRenderer will now recalculate the vertexOffset correctly if the batch flushes, fixing an issue where it would display missing triangles in a mesh after a batch flush. Fix #6814 (thanks @pavels)
  • The NineSlice Game Object will now guard against an invalid texture by checking for the frame and textureFrame vars before trying to read values from them. Fix #6804 (thanks @IvanDem)
  • DOM Game Elements are now kept in the correct position when a Scene camera zooms out. Previously, they only worked if you kept their origin at 0x0, or didn't zoom the camera out. Fix #6817 #6607 (thanks @moufmouf)

Input Bug Fixes

  • The method pointer.leftButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.rightButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.middleButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.backButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.forwardButtonReleased will now return true when multiple mouse buttons are being pressed. Fix #6027 (thanks @michalfialadev)

Examples, Documentation, Beta Testing and TypeScript

Thanks to the following for helping with the Phaser Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@AlbertMontagutCasero @Andrek25 @Antriel @leha-games @lgtome @monteiz @rexrainbow @saintflow47 @samme @ssotangkur @vankop

Deprecation Warning for the next release

The next release of Phaser will make the following API-breaking changes:

  • We are removing Phaser.Struct.Map and replacing it with a regular JS Map instance. This means methods like contains and setAll will be gone.
  • We are removing Phaser.Struct.Set and replacing it with a regular JS Set instance. This means methods like iterateLocal will be gone.
  • The Create.GenerateTexture, all of the Create Palettes and the create folder will be removed.
  • The phaser-ie9.js entry-point will be removed along with all associated polyfills.
  • The Spine 3 and Spine 4 plugins will no longer be updated. You should now use the official Phaser Spine plugin created by Esoteric Software.
  • The Geom.Point class and all related functions will be removed. All functionality for this can be found in the existing Vector2 math classes. All Geometry classes that currently create and return Point objects will be updated to return Vector2 objects instead.
  • We will be moving away from Webpack and using ESBuild to build the next version of Phaser.

- JavaScript
Published by photonstorm over 1 year ago

phaser - Phaser v3.85.0 Beta 2

Version 3.85.0 - Itsuki - in development

Round Pixels

Includes a Potentially Breaking Change

The way roundPixels has been handled in this release has been changed significantly. In previous versions we passed a uniform to the shaders and handled the pixel rounding on the GPU. However, this caused issues with our batching flow - for example, a Sprite would need to be rounded, but a Text or Shape object would not. This lead to complications in some parts of the render code.

In this release we have removed the shader uniform and branching and also made roundPixels default to false in the Game Config. Previously, it was true, so you may need to switch this flag if you were relying on it. Here are the results of this change:

  • The Game Config roundPixels property now defaults to false.
  • The uRoundPixels uniform has been removed from the Single, Multi and Mobile vertex shaders.
  • Setting the uRoundPixels uniform has been removed from the Single, Rope, PreFX, PostFX, Multi and Mobile WebGL Pipelines.
  • The Multi Pipeline and Blitter WebGL Renderer will now pass the camera.roundPixels value to the Transform Matrix setQuad method.
  • The Multi Pipeline batchSprite and batchTexture methods will now apply Math.floor to the sprite matrix calculations if camera round pixels is enabled.
  • BaseCamera.preRender has been removed. This method was completely overridden by Camera.preRender which is the method that contained the correct rendering logic. As the Base Camera variant was not used internally outside of Dynamic Textures, we have removed it to save space.
  • Camera.preRender has been updated to use both zoomX and zoomY for the matrix transform.
  • Camera.preRender has been updated to apply Math.floor to the scroll factor when rounding is enabled on the Camera. This fixes an issue where following sprites with Camera lerp, or heavy zoom factors, would cause 'stuttering' at sub-pixel values.

New Features

  • BaseSoundManager.isPlaying is a new method that will return a boolean if the given sound key is playing. If you don't provide a key, it will return a boolean if any sound is playing (thanks @samme)
  • WebGLRenderer.dispatchContextLost is a new internal method that 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, be sure to invoke this method in due course.
  • WebGLRenderer.dispatchContextRestore is a new internal method that is called when the WebGL context is restored. By default this is bound to the property WebGLRenderer.contextRestoreHandler. If you override the context restore handler, be sure to invoke this method in due course.
  • WebGLRenderer.setContextHandlers is a new internal method with 2 optional parameters: contextLost and contextRestored. These allow you to overwrite the default contextLostHandler and contextRestoreHandler handlers. (thanks @yaustar)
  • Phaser.Textures.Frame#setCutPosition is a new internal method with 2 optional parameters: x and y. These sets the x and y position within the source image to cut from.
  • Phaser.Textures.Frame#setCutSize is a new internal method with 2 parameters: width and height. These sets the width, and height of the area in the source image to cut. (thanks @FelipeIzolan)
  • Introduced new constants in ORIENTATION_CONST. The constants LANDSCAPE_SECONDARY and PORTRAIT_SECONDARY have been added to the Phaser.Scale.Orientation object. These constants represent the secondary landscape and portrait orientations respectively. This addition provides more granular control over device orientation handling in Phaser. Fix #6837 (thanks @rexrainbow)
  • Introduced updateConfig method in ParticleEmitter to allow dynamic updating of Particle Emitter configurations. This method enables existing properties to be overridden and new properties to be added to the emitter's configuration. It ensures that the emitter is reset with the updated configuration for more flexible particle effects management.
  • A new wrap method has been natively integrated into the Body class to replace the existing MatterWrap plugin. Here's how it works.
  • The Matter attractors plugin has been natively integrated into the Body class and Matter engine. More details here.
  • Added functionality to the Phaser.Textures.DynamicTexture#clear method. Clear a specific area within a Dynamic Texture by specifying x, y, width, and height parameters to clear only a portion of the texture. Fix #6853 (thanks @SelfDevTV)
  • Added functionality to the Phaser.Renderer.WebGL.RenderTarget#clear method. Clear a specific area within the RenderTarget by specifying x, y, width, and height parameters.
  • Added Default Image Handling in TextureManager. In the game config, set defaultImage to null to ignore loading the defaultImage.
  • Added Missing Image Handling in TextureManager. In the game config, set missingImage to null to ignore loading the missingImage.
  • Added White Image Support in TextureManager. In the game config, set whiteImage to null to ignore loading the whiteImage.
  • Phaser.Core.TimeStep#pauseDuration is a new property that holds the duration of the most recent game pause, if any, in ms (thanks @samme)
  • The Game Events#RESUME event now contains a new parameter pauseDuration which is the duration, in ms, that the game was paused for (thanks @samme)
  • Added Phaser.Loader.LoaderPlugin#removePack method to LoaderPlugin that removes resources listed in an Asset Pack.(thanks @samme)

WebGL Rendering Updates

  • WebGLTextureWrapper.update expanded:
    • source parameter is now type ?object, so it can be used for anything that is valid in the constructor.
    • New format parameter can update the texture format.

Updates

  • MatterJS updated to 0.20.0 and integrated into Phaser. Here are details about the update.
  • Integrated MatterCollisionEvents plugin functionality directly into the Matter.World class to handle collisions more effectively. More details here.
  • Updated Matter.World to improve the performance, accuracy, and reliability of the update method in handling physics simulations or animations. More details here.
  • Calling Timeline.pause will now pause any currently active Tweens that the Timeline had started (thanks @monteiz)
  • Calling Timeline.resume will now resume any currently paused Tweens that the Timeline had started (thanks @monteiz)
  • Calling Timeline.clear and Timeline.destroy will now destroy any currently active Tweens that the Timeline had created. Previously, active tweens would continue to play to completion (thanks @monteiz)
  • TimelineEvent has a new property called tweenInstance. If the Timeline event has a tween that has been activated, this will hold a reference to it.
  • If you create a BitmapText with an invalid key it will now throw a runtime error. Previously it just issued a console warning and then crashed (thanks @samme)
  • The console warnings when Audio files are missing/incorrect have been improved (thanks @samme)
  • The requestVideoFrame polyfill has been updated to the latest release, which should resolve some SSR framework issues. Fix #6776 (thanks @lantictac)
  • ScaleManager listeners includes checks for the screen.orientation object and adds/removes a change eventListener method to handle screen orientation changes on mobile devices. The orientationchange event is still maintained for backwards compatibility. Fix #6837 (thanks @rexrainbow)
  • When creating a new TileSprite, setting either width or height to 0 results in both values being set to the displayFrame.width and displayFrame.height. The updated logic now checks for width and height separately. If width is 0, it is set to displayFrame.width. If height is 0, it is set to displayFrame.height. Fix #6857 (thanks @GaryStanton)
  • Updated GetBitmapTextSize with improved maxWidth calculations for wrapped text.
  • Vector3.subVectors is a new method that will take 2 Vector3s, subtract them from each other and store the result in the Vector3 it was called on.
  • The TextStyle.setStyle method will no longer mutate the given style object if it includes a numeric fontSize value. Fix #6863 (thanks @stormpanda)
  • Calling the Shape.Ellipse.setSize method will internally call updateDisplayOrigin to retain position after a size change.
  • The BitmapText BatchChar function now inlines all of the matrix math, avoiding 16 function calls per character rendered.

Bug Fixes

  • The activePointers game config option is now the correct amount of touch input pointers set. Fix #6783 (thanks @samme)
  • The method TextureManager.checkKey will now return false if the key is not a string, which fixes issues where a texture could be created if a key was given that was already in use (thanks Will Macfarlane).
  • Added all of the missing Loader Config values (such as imageLoadType) to LoaderConfig, so they now appear in the TypeScript defs.
  • The EXPAND scale mode had a bug that prevented it from using the world bounds cameras, cutting rendering short. Fix #6767 (thanks @Calcue-dev @rexrainbow)
  • Calling getPipelineName() on a Game Object would cause a runtime error if running under Canvas. It now simply returns null. Fix #6799 (thanks @samme)
  • Calling the Arcade Body setPushable(false) method for circle bodies prevents the bodies from being pushed. Fix #5617 (thanks @kainage)
  • Calling addDeathZone() on a particle emitter Game Object had a bug where the DeathZone used world position coordinates. DeathZone now uses local position coordinates following the particle emitter position. Fix #6371 (thanks @vforsh)
  • Updated the GetLineToLine method in GetLineToLine to handle the case where dx1 or dy1 values is zero. This ensures the function correctly returns null in this case to prevent errors in calculations involving line segments. Fix #6579 (thanks @finscn)
  • Resolved all kerning issues in WebGL bitmap text rendering. This includes adjustments to glyph positioning and spacing, ensuring accurate and visually pleasing text display across all WebGL contexts. Fix #6631 (thanks @monteiz)
  • Fixed Matter.World bug where group.length returns undefined. Changed to group.getLength() to correctly return number of children in a group.
  • Fixed Group vs Group collisions failing when performing a bitwise & operation between body1.collisionMask and body2.collisionCategory. The default collisionMask value is changed to 2147483647 to correctly match any collisionCategory. Fix #6764 (thanks @codeimpossible)
  • Resolved an issue in BitmapText where adding a space character ' ' at the end of a line did not correctly align the vertical position of the new line. The updated calculation now correctly accounts for both line height and line spacing. Fix #6717 (thanks @wooseok123)
  • Resolved an issue in BitmapText where an extra empty line was added when setMaxWidth was called, and the width of the line was less than a word. Previously, yAdvance was incorrectly incremented by lineHeight + lineSpacing for each word, leading to an unintended increase in vertical space. The correction now calculates yAdvance based on the currentLine index, ensuring that vertical spacing accurately reflects the number of lines. Fix #6807 (thanks @AlvaroNeuronup)
  • Resolved an issue in BitmapText where adding a space character ' ' at the end of a line caused the following line of to ignore line wrapping when using setMaxWidth. Fix #6860 (thanks @bagyoni)
  • The Matrix4.lookAtRH method would fail because it called two missing Vector3 methods.
  • The RenderTarget will now automatically listen for the Renderer resize event if autoResize is true. This fixes an issue with Bitmap Masks where they wouldn't resize if the renderer resized. Fix #6769 (thanks @pavels)
  • The Texture.getFrameBounds method will now include the BASE texture in its calculations. This prevents it from returning a size of Infinity. This fixes an issue where a Tileset with margin/spacing loaded via load.spritesheet instead of load.image would have its margin and spacing ignored. Fix #6823 (thanks @damian-pastorini)

Input Bug Fixes

  • The method pointer.leftButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.rightButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.middleButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.backButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.forwardButtonReleased will now return true when multiple mouse buttons are being pressed. Fix #6027 (thanks @michalfialadev)

Examples, Documentation, Beta Testing and TypeScript

Thanks to the following for helping with the Phaser Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@lgtome @samme @AlbertMontagutCasero @rexrainbow

Deprecation Warning for the next release

The next release of Phaser will make the following API-breaking changes:

  • We are removing Phaser.Struct.Map and replacing it with a regular JS Map instance. This means methods like contains and setAll will be gone.
  • We are removing Phaser.Struct.Set and replacing it with a regular JS Set instance. This means methods like iterateLocal will be gone.
  • The Create.GenerateTexture, all of the Create Palettes and the create folder will be removed.
  • The phaser-ie9.js entry-point will be removed along with all associated polyfills.
  • The Spine 3 and Spine 4 plugins will no longer be updated. You should now use the official Phaser Spine plugin created by Esoteric Software.

- JavaScript
Published by photonstorm almost 2 years ago

phaser - Phaser v3.85.0 Beta 1

Version 3.85.0 - Itsuki - in development

New Features

  • BaseSoundManager.isPlaying is a new method that will return a boolean if the given sound key is playing. If you don't provide a key, it will return a boolean if any sound is playing (thanks @samme)
  • WebGLRenderer.dispatchContextLost is a new internal method that 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, be sure to invoke this method in due course.
  • WebGLRenderer.dispatchContextRestore is a new internal method that is called when the WebGL context is restored. By default this is bound to the property WebGLRenderer.contextRestoreHandler. If you override the context restore handler, be sure to invoke this method in due course.
  • WebGLRenderer.setContextHandlers is a new internal method with 2 optional parameters: contextLost and contextRestored. These allow you to overwrite the default contextLostHandler and contextRestoreHandler handlers. (thanks @yaustar)
  • Phaser.Textures.Frame#setCutPosition is a new internal method with 2 optional parameters: x and y. These sets the x and y position within the source image to cut from.
  • Phaser.Textures.Frame#setCutSize is a new internal method with 2 parameters: width and height. These sets the width, and height of the area in the source image to cut. (thanks @FelipeIzolan)
  • Introduced new constants in ORIENTATION_CONST.js. The constants LANDSCAPE_SECONDARY and PORTRAIT_SECONDARY have been added to the Phaser.Scale.Orientation object. These constants represent the secondary landscape and portrait orientations respectively. This addition provides more granular control over device orientation handling in Phaser. Fix #6837 (thanks @rexrainbow)

WebGL Rendering Updates

  • WebGLTextureWrapper.update expanded:
    • source parameter is now type ?object, so it can be used for anything that is valid in the constructor.
    • New format parameter can update the texture format.

Updates

  • Calling Timeline.pause will now pause any currently active Tweens that the Timeline had started (thanks @monteiz)
  • Calling Timeline.resume will now resume any currently paused Tweens that the Timeline had started (thanks @monteiz)
  • Calling Timeline.clear and Timeline.destroy will now destroy any currently active Tweens that the Timeline had created. Previously, active tweens would continue to play to completion (thanks @monteiz)
  • TimelineEvent has a new property called tweenInstance. If the Timeline event has a tween that has been activated, this will hold a reference to it.
  • If you create a BitmapText with an invalid key it will now throw a runtime error. Previously it just issued a console warning and then crashed (thanks @samme)
  • The console warnings when Audio files are missing/incorrect have been improved (thanks @samme)
  • The requestVideoFrame polyfill has been updated to the latest release, which should resolve some SSR framework issues. Fix #6776 (thanks @lantictac)
  • ScaleManager listeners includes checks for the screen.orientation object and adds/removes a change eventListener method to handle screen orientation changes on mobile devices. The orientationchange event is still maintained for backwards compatibility. Fix #6837 (thanks @rexrainbow)

Bug Fixes

  • The activePointers game config option is now the correct amount of touch input pointers set. Fix #6783 (thanks @samme)
  • The method TextureManager.checkKey will now return false if the key is not a string, which fixes issues where a texture could be created if a key was given that was already in use (thanks Will Macfarlane).
  • Added all of the missing Loader Config values (such as imageLoadType) to LoaderConfig, so they now appear in the TypeScript defs.
  • The EXPAND scale mode had a bug that prevented it from using the world bounds cameras, cutting rendering short. Fix #6767 (thanks @Calcue-dev @rexrainbow)
  • Calling getPipelineName() on a Game Object would cause a runtime error if running under Canvas. It now simply returns null. Fix #6799 (thanks @samme)
  • Calling the Arcade Body setPushable(false) method for circle bodies prevents the bodies from being pushed. Fix #5617 (thanks @kainage)
  • Calling addDeathZone() on a particle emitter Game Object had a bug where the DeathZone used world position coordinates. DeathZone now uses local position coordinates following the particle emitter position. Fix #6371 (thanks @vforsh)
  • Updated the GetLineToLine method in GetLineToLine.js to handle the case where dx1 or dy1 values is zero. This ensures the function correctly returns null in this case to prevent errors in calculations involving line segments. Fix #6579 (thanks @finscn)
  • Resolved all kerning issues in WebGL bitmap text rendering. This includes adjustments to glyph positioning and spacing, ensuring accurate and visually pleasing text display across all WebGL contexts. Fix #6631 (thanks @monteiz)
  • Resolved an issue in GetBitmapTextSize.js where an extra empty line was added when setMaxWidth was called, and the width of the line was less than a word. Previously, yAdvance was incorrectly incremented by lineHeight + lineSpacing for each word, leading to an unintended increase in vertical space. The correction now calculates yAdvance based on the currentLine index, ensuring that vertical spacing accurately reflects the number of lines. Fix #6807 (thanks @AlvaroNeuronup)

Input Bug Fixes

  • The method pointer.leftButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.rightButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.middleButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.backButtonReleased will now return true when multiple mouse buttons are being pressed.
  • The method pointer.forwardButtonReleased will now return true when multiple mouse buttons are being pressed. Fix #6027 (thanks @michalfialadev)

Examples, Documentation, Beta Testing and TypeScript

Thanks to the following for helping with the Phaser Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@lgtome @samme @AlbertMontagutCasero @rexrainbow

Deprecation Warning for the next release

The next release of Phaser will make the following API-breaking changes:

  • We are removing Phaser.Struct.Map and replacing it with a regular JS Map instance. This means methods like contains and setAll will be gone.
  • We are removing Phaser.Struct.Set and replacing it with a regular JS Set instance. This means methods like iterateLocal will be gone.
  • The Create.GenerateTexture, all of the Create Palettes and the create folder will be removed.
  • The phaser-ie9.js entry-point will be removed along with all associated polyfills.

- JavaScript
Published by photonstorm almost 2 years ago

phaser - Phaser v3.80.1

Please also see the 3.80 Change Log for details about the major 3.80 release.

Bug Fixes

  • Fix RenderTexture crashing in the presence of a light.
  • Fix failure to restore compressed textures after WebGL context loss.
  • Fix a single WebGL error, with no visual side-effects, from occurring while calling Shader.setRenderToTexture() after the game has started running. Actually, the root cause was leaving new WebGL textures bound after creation.
  • Ensure that TextureSource.setFlipY always updates the texture.
  • Remove unsynced flipY from render textures in Shader and DynamicTexture.
  • Reverted a change made in TouchManager that would prevent clicks from outside the game window from being registered. Fix #6747 (thanks @ulsoftnaver @jaxtheking)

Updates

  • Modified onMouseUpWindow and onMouseDownWindow in the MouseManager so they now check for sourceCapabilities.firesTouchEvents and if found, abort registering the event. This new browser event property is designed to prevent you accidentally registering a Mouse Event when a Touch Event has just occurred (see https://developer.mozilla.org/en-US/docs/Web/API/InputDeviceCapabilities/firesTouchEvents)

- JavaScript
Published by photonstorm over 2 years ago

phaser - Phaser v3.80.0

New Features - WebGL Context Loss Handling

  • Phaser now performs a WebGL Context Restore to keep the game running after losing WebGL context. This affects many parts of the rendering system, but everything should work just the same unless you're doing something very technical. See the link for more details.

New Feature - Base64 Loader

The Phaser LoaderPlugin and related classes have been updated so that they now work natively with base64 encoded files and Data URIs. This means you can now load a base64 encoded image, audio file or text file directly into the Loader. The Loader will then decode the data and process it as if it was a normal file. This is particularly useful for environments such as Playable Ads where you have to provide a single html file with all assets embedded and no XHR requests.

  • Loader.File.base64 is a new read-only boolean property that is set if the file contains a Data URI encoded string.
  • Loader.File.onBase64Load is a new method that is called when the file has finished decoding from a Data URI.
  • The ImageFile will now default to using the Image Load Element if a base64 file is detected, instead of throwing a console warning about unsupported types.
  • The XHRLoader will now return a fake XHR result object containing the decoded base64 data if a base64 file is detected, skipping the creation of a real XML Http Request object.

New Feature - Scale Manager Snap Mode

The Game Config has a new Scale Manager property called snap. This allows you to set a 'snapping' value for the width and height of your game. This is especially useful for games where you want to keep a fixed dimension: for example, you want the game to always snap to a multiple of 16 pixels for the width. Or, if you want to scale a pixel-art game up by integer values, you can now set the game size as the snap value and the Scale Manager will ensure the game size is always a multiple of that value.

  • A new property is available in the Game Configuration specifically for setting the 'snap' values for the Scale Manager. You can now set snap: { width, height } in the game config. This is then passed to the display size by the Scale Manager and used to control the snap values. Fix #6629 (thanks @musjj @samme)
  • ScaleManager.setSnap is a new method that allows you to set the snap values for the game size, should you need to do it post-boot and not in the game config.
  • Config#snapWidth and Config#snapHeight are new properties in the Game Config that hold the parsed snap config values, as used by the Scale Manager.

New Features

  • The Scale Manager has a new scale mode called EXPAND. This is inspired by the Expand mode in Godot: "Keep aspect ratio when stretching the screen, but keep neither the base width nor height. Depending on the screen aspect ratio, the viewport will either be larger in the horizontal direction (if the screen is wider than the base size) or in the vertical direction (if the screen is taller than the original size)" (thanks @rexrainbow)
  • The Tilemap.createFromTiles method has been updated. It will now copy the following properties, if set in the Tile, to the Sprites it creates: rotation, flipX, flipY, alpha, visible and tint. If these properties are declared in the spriteConfig passed to the method, those will be used instead, otherwise the Tile values are used. Fix #6711 (thanks @Nerodon)
  • The Tilemap.createFromTiles method has a new 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. Also, if you have not specified an origin in the spriteConfig, it will adjust the sprite positions by half the tile size, to position them accurately on the map.
  • Texture#getFrameBounds is a new method that will return the bounds that all of the frames of a given Texture Source encompass. This is useful for things like calculating the bounds of a Sprite Sheet embedded within a Texture Atlas.
  • Math.RectangleLike is a new typedef that defines a rectangle-like object with public x, y, width and height properties.

WebGL Renderer Updates

  • Fix MIPmap filters being effectively disabled for compressed textures.
  • WebGLRenderer.getCompressedTextures can now identify BPTC and RGTC support correctly. These were previously skipped.
  • PVR compressed texture files now support sRGB color space in S3TCSRGB, ETC, and ASTC formats. Fix #6247 (thanks @dominikhalvonik)
  • Compressed texture files which are incompatible with WebGL will now fail to load, and display a console warning explaining why. Previously they might seem to load, but not display properly.
  • Add experimental support for BPTC compressed textures in PVR files.
  • Change S3TCRGB to S3TCSRGB in WebGLTextureCompression, CompressedTextureFileConfig, and FileConfig typedefs.
  • Fix generating spritesheets from members of texture atlases based on compressed textures (thanks @vladyslavfolkuian)
  • 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 bind the current Render Target after the pipeline has booted for the first time. This fixes glitch errors on mobile devices where Post FX would appear corrupted for a single frame. Fix #6681 (thanks @moufmouf @tongliang999)
  • Fix unpredictable text sizes failing to render in WebGL with mipmapFilter set. Fix #6721 (thanks @saintflow and @rexrainbow)
  • 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.
  • WebGLPipeline.resizeUniform is a new property that is defined in the WebGLPipelineConfig. This is a string that defines a uResolution property, or similar, within the pipeline shader. If the WebGL Renderer resizes, this uniform will now be updated automatically as part of the pipeline resize method. It has been added to both the Multi and Mobile pipelines as default. This fixes issues where the pipelines were rendering with old resolution values, causing graphical glitches in mostly pixel-art games. Fix #6674 #6678 (thanks @Nerodon @LazeKer)

Spine Updates

  • The Spine 3 and 4.1 Plugins will now call preUpdate automatically when the play method is called. This forces the new animation state to update and apply itself to the skeleton. This fixes an issue where Spine object would show the default frame in the Spine atlas for a single update before the animation started. Fix #5443 (thanks @spayton)
  • SpineGameObject.setSlotAlpha is a new method that allows you to set the alpha on a specific slot in a Spine skeleton.
  • The SpineGameObject.setAlpha method has had its 2nd parameter removed. This fixes needless slot look-ups during rendering when a Spine Game Object is inside a regular Container. If you need to set slot alpha, use the new setSlotAlpha method instead. Fix #6571 (thanks @spayton)
  • The SpineFile.onFileComplete handler was running a regular expression against file.src instead of file.url, sometimes leading to double paths in the atlas paths on loading. Fix #6642 (thanks @rez23)

Input Updates

The Phaser Input and related classes have been updated to be more consistent with each Game Object.

  • If you enable a Game Object for Input Debugging, the debug shape will no longer be rendered if the Game Object itself is not visible. Fix #6364 (thanks @orjandh)
  • Mesh based Game Objects now can use an input config with the setInteractive method, which supports the options draggable, dropzone, cursor and userHandCursor. Fix #6510 #6652 (thanks @Baegus @Neppord)
  • The touch event handler onTouchEndWindow now stops pointer events when clicking through DOM elements to input. Fix #6697 (thanks @laineus)
  • The Input.InputPlugin method disable which is called by GameObjects.GameObject#disableInteractive keeps its temp hit box value which stops propagation to interactive Game Objects in another scene. Fix #6601 (thanks @UnaiNeuronUp)
  • Using setInteractive and removeInteractive methods of a Game Object outside of the game loop would cause an error in which Input.InputManager#resetCursor would lose input context. Fix #6387 (thanks @TomorrowToday)

Updates

  • The TweenChainBuilder was incorrectly setting the persist flag on the Chain to true, which goes against what the documentation says. It now correctly sets it to false. This means if you previously had a Tween Chain that was persisting, it will no longer do so, so add the property to regain the feature.
  • The dropped argument has now been added 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 ADDEDTOSCENE 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.
  • The Tilemaps.Components.WeightedRandomize method 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 anyway. (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 Game Object has had its removeAll, remove and add methods 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 Actions method PlaceOnLine now has an added ease parameter which accepts a string from the EaseMap or a custom ease function to allow for different distributions along a line. (thanks @sB3p)
  • The XHRLoader will now listen for ontimeout and if triggered it will hand over to the File.onError handler. This prevents the Loader from stalling if a file times out. Fix #6472 (thanks @343dev)
  • LightPipeline.currentNormalMap was incorrectly documented as being a property of WebGLRenderer.
  • The Video Game Object now emits a metadata event, which emits once the video metadata is available.
  • The Time.Timeline class now supports looping via the repeat method. Types.Time.TimelineEvent now has a loop callback which will be called before its next iteration. Fix #6560 (thanks @micsun-al)
  • The Curves.Path methods lineTo and moveTo now support Types.Math.Vector2Like as the first parameter. Fix #6557 (thanks @wayfu)
  • The BitmapText.setFont method will now set the texture, size and alignment even if the same font key has been given as is already in use. Fix #6740 (thanks @AlvaroNeuronup)
  • WebAudioSound will now set hasEnded = false as part of stopAndRemoveBufferSource, after the source has been stopped and disconnected. This should prevent it from being left in a true state if the source onended callback fired late, after the sound had been re-played. Fix #6657 (thanks @Demeno)
  • The ScaleManager.orientationChange event listener will now directly refresh the Scale Manager internals. This fixes an issue where the orientation change event would fire after the window resize event, causing the Scale Manager to incorrectly report the new orientation on Chrome on iOS. Fix #6484 #5762 (thanks @spayton @meetpatel1989)
  • The Tileset.updateTileData method has two new optional parameters offsetX and offsetY which allow you to set the offset that the tile data starts from within the base source texture.

Bug Fixes

  • 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)
  • The Animations.AnimationFrame member duration is now the complete duration of the frame, which is a breaking change. Before this Animations.AnimationState#msPerFrame was combined with Animations.AnimationFrame#duration which wasn't intuitive. The fix to remove Animations.AnimationState#msPerFrame from Animations.AnimationFrame#duration has been removed from the Animations.AnimationManager method 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. Fix #6713 (thanks @dhashvir)
  • The NineSlice Game Object method no longer defaults origin to 0.5. Fix #6655 (thanks @michalfialadev)
  • 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 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 the RandomDataGenerator.weightedPick method to avoid sampling past the last element. Fix #6701 (thanks @jameskirkwood)
  • The Physics.Matter.Factory method pointerConstraint no longer returns an error when it can't find the camera. Fix #6684 (thanks @spritus)
  • The Physics.Arcade.StaticBody method reset now re-applies offset values. Fix #6729 (thanks @samme)
  • The Video Game Object now has a starting texture, which stops errors with accessing frame before the video loads the first frame. Fix #6475 (thanks @rexrainbow @JoeSiu)
  • The Device.Browser.safari regular expression has been strenghtened so it now captures versions with double or triple periods in. Previously it would fail for Version/17.2.1 due to the minor value. (thanks watcher)
  • The Browser Device class will no longer think that Chrome is Mobile Safari on iOS devices. Fix #6739 (thanks @michalfialadev)
  • The GameObjectCreator method container now includes all children in the config, accessed via Scene.make.container. Fix #6743 (thanks @Fake)
  • Tilemaps that have been created using Tiles taken from a Sprite Sheet embedded in a Texture Atlas (via addSpriteSheetFromAtlas and Tilemap.addTilesetImage) will now render correctly. Fix #6691 (thanks @Antriel)
  • The TilemapWebGLRenderer function has been fixed so it now uses the TileSet width and height for the tile draw command. This fixes an issue where the Tilemap would render incorrectly if the base tile size was different to the tile size. Fix #5988 (thanks @samme)
  • The ArcadePhysics.World.collideSpriteVsTilemapLayer method has been modified so that the body bounds are now expanded by the size of the scaled base tile in the Tilemap Layer. This fixes an issue where the check would skip over-sized tiles that were outside the bounds of the body. Mostly noticeable on layers that had a different base tile size to the map itself. Fix #4479 (thanks @KingCosmic)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@actionmoon @AlvaroEstradaDev @Byvire @Creepypoke @Flashfyre @orcomarcio @paxperscientiam @michalfialadev @rafael-lua @samme @Stan-Stani @stevenwithaph @yaustar @rexrainbow

- JavaScript
Published by photonstorm over 2 years ago

phaser - Phaser v3.80.0 Beta 2

Version 3.80.0 - Nino - in dev

New Features

  • The Scale Manager has a new scale mode called EXPAND. This is inspired by the Expand mode in Godot: "Keep aspect ratio when stretching the screen, but keep neither the base width nor height. Depending on the screen aspect ratio, the viewport will either be larger in the horizontal direction (if the screen is wider than the base size) or in the vertical direction (if the screen is taller than the original size)" (thanks @rexrainbow)
  • Phaser now performs a WebGL Context Restore to keep the game running after losing WebGL context. This affects many parts of the rendering system, but everything should work just the same unless you're doing something very technical. See the link for more details.

New Features - Base64 Loader

The Phaser LoaderPlugin and related classes have been updated so that they now work natively with base64 encoded files and Data URIs. This means you can now load a base64 encoded image, audio file or text file directly into the Loader. The Loader will then decode the data and process it as if it was a normal file. This is particularly useful for environments such as Playable Ads where you have to provide a single html file with all assets embedded and no XHR requests.

  • Loader.File.base64 is a new read-only boolean property that is set if the file contains a Data URI encoded string.
  • Loader.File.onBase64Load is a new method that is called when the file has finished decoding from a Data URI.
  • The ImageFile will now default to using the Image Load Element if a base64 file is detected, instead of throwing a console warning about unsupported types.
  • The XHRLoader will now return a fake XHR result object containing the decoded base64 data if a base64 file is detected, skipping the creation of a real XML Http Request object.

Spine Updates

  • The Spine 3 and 4.1 Plugins will now call preUpdate automatically when the play method is called. This forces the new animation state to update and apply itself to the skeleton. This fixes an issue where Spine object would show the default frame in the Spine atlas for a single update before the animation started. Fix #5443 (thanks @spayton)
  • SpineGameObject.setSlotAlpha is a new method that allows you to set the alpha on a specific slot in a Spine skeleton.
  • The SpineGameObject.setAlpha method has had its 2nd parameter removed. This fixes needless slot look-ups during rendering when a Spine Game Object is inside a regular Container. If you need to set slot alpha, use the new setSlotAlpha method instead. Fix #6571 (thanks @spayton)
  • The SpineFile.onFileComplete handler was running a regular expression against file.src instead of file.url, sometimes leading to double paths in the atlas paths on loading. Fix #6642 (thanks @rez23)

Updates

  • The TweenChainBuilder was incorrectly setting the persist flag on the Chain to true, which goes against what the documentation says. It now correctly sets it to false. This means if you previously had a Tween Chain that was persisting, it will no longer do so, so add the property to regain the feature.
  • 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 ADDEDTOSCENE 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.
  • The Tilemaps.Components.WeightedRandomize method 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 Game Object has had its removeAll, remove and add methods 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)
  • If you enable a Game Object for Input Debugging, the debug shape will no longer be rendered if the Game Object itself is not visible. Fix #6364 (thanks @orjandh)
  • The XHRLoader will now listen for ontimeout and if triggered it will hand over to the File.onError handler. This prevents the Loader from stalling if a file times out. Fix #6472 (thanks @343dev)
  • LightPipeline.currentNormalMap was incorrectly documented as being a property of WebGLRenderer.
  • Mesh based Game Objects now can use an input config with the setInteractive method, which supports the options draggable, dropzone, cursor and userHandCursor. Fix #6510 #6652 (thanks @Baegus @Neppord)

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)
  • The Animations.AnimationFrame member duration is now the complete duration of the frame, which is a breaking change. Before this Animations.AnimationState#msPerFrame was combined with Animations.AnimationFrame#duration which wasn't intuitive. The fix to remove Animations.AnimationState#msPerFrame from Animations.AnimationFrame#duration has been removed from the Animations.AnimationManager method 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 (thanks @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 the RandomDataGenerator.weightedPick method to avoid sampling past the last element. Fix #6701 (thanks @jameskirkwood)
  • The touch event handler onTouchEndWindow now stops pointer events when clicking through DOM elements to input. Fix #6697 (thanks @laineus)
  • The Physics.Matter.Factory method pointerConstraint no longer returns an error when it can't find the camera. Fix #6684 (thanks @spritus)
  • The Physics.Arcade.StaticBody method reset now re-applies offset values. Fix #6729 (thanks @samme)
  • The Input.InputPlugin method disable which is called by GameObjects.GameObject#disableInteractive keeps its temp hit box value which stops propagation to interactive Game Objects in another scene. Fix #6601 (thanks @UnaiNeuronUp)
  • Using setInteractive and removeInteractive methods of a Game Object outside of the game loop would cause an error in which Input.InputManager#resetCursor would lose input context. Fix #6387 (thanks @TomorrowToday)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@AlvaroEstradaDev @stevenwithaph @paxperscientiam @samme @actionmoon @rafael-lua @Byvire

- JavaScript
Published by photonstorm over 2 years ago

phaser - Phaser v3.80.0 Beta 1

Version 3.80.0 - Nino - in dev

New Features

  • The Scale Manager has a new scale mode called EXPAND. This is inspired by the Expand mode in Godot: "Keep aspect ratio when stretching the screen, but keep neither the base width nor height. Depending on the screen aspect ratio, the viewport will either be larger in the horizontal direction (if the screen is wider than the base size) or in the vertical direction (if the screen is taller than the original size)" (thanks @rexrainbow)
  • Phaser now performs a WebGL Context Restore to keep the game running after losing WebGL context. This affects many parts of the rendering system, but everything should work just the same unless you're doing something very technical. See the link for more details.

New Features - Base64 Loader

The Phaser LoaderPlugin and related classes have been updated so that they now work natively with base64 encoded files and Data URIs. This means you can now load a base64 encoded image, audio file or text file directly into the Loader. The Loader will then decode the data and process it as if it was a normal file. This is particularly useful for environments such as Playable Ads where you have to provide a single html file with all assets embedded and no XHR requests.

  • Loader.File.base64 is a new read-only boolean property that is set if the file contains a Data URI encoded string.
  • Loader.File.onBase64Load is a new method that is called when the file has finished decoding from a Data URI.
  • The ImageFile will now default to using the Image Load Element if a base64 file is detected, instead of throwing a console warning about unsupported types.
  • The XHRLoader will now return a fake XHR result object containing the decoded base64 data if a base64 file is detected, skipping the creation of a real XML Http Request object.

Spine Updates

  • The Spine 3 and 4.1 Plugins will now call preUpdate automatically when the play method is called. This forces the new animation state to update and apply itself to the skeleton. This fixes an issue where Spine object would show the default frame in the Spine atlas for a single update before the animation started. Fix #5443 (thanks @spayton)
  • SpineGameObject.setSlotAlpha is a new method that allows you to set the alpha on a specific slot in a Spine skeleton.
  • The SpineGameObject.setAlpha method has had its 2nd parameter removed. This fixes needless slot look-ups during rendering when a Spine Game Object is inside a regular Container. If you need to set slot alpha, use the new setSlotAlpha method instead. Fix #6571 (thanks @spayton)
  • The SpineFile.onFileComplete handler was running a regular expression against file.src instead of file.url, sometimes leading to double paths in the atlas paths on loading. Fix #6642 (thanks @rez23)

Updates

  • The TweenChainBuilder was incorrectly setting the persist flag on the Chain to true, which goes against what the documentation says. It now correctly sets it to false. This means if you previously had a Tween Chain that was persisting, it will no longer do so, so add the property to regain the feature.
  • 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 ADDEDTOSCENE 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.
  • The Tilemaps.Components.WeightedRandomize method 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 Game Object has had its removeAll, remove and add methods 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)
  • If you enable a Game Object for Input Debugging, the debug shape will no longer be rendered if the Game Object itself is not visible. Fix #6364 (thanks @orjandh)
  • The XHRLoader will now listen for ontimeout and if triggered it will hand over to the File.onError handler. This prevents the Loader from stalling if a file times out. Fix #6472 (thanks @343dev)

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)
  • The Animations.AnimationFrame member duration is now the complete duration of the frame, which is a breaking change. Before this Animations.AnimationState#msPerFrame was combined with Animations.AnimationFrame#duration which wasn't intuitive. The fix to remove Animations.AnimationState#msPerFrame from Animations.AnimationFrame#duration has been removed from the Animations.AnimationManager method 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 (thanks @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 the RandomDataGenerator.weightedPick method to avoid sampling past the last element. Fix #6701 (thanks @jameskirkwood)
  • The touch event handler onTouchEndWindow now stops pointer events when clicking through DOM elements to input. Fix #6697 (thanks @laineus)
  • The Physics.Matter.Factory method pointerConstraint no longer returns an error when it can't find the camera. Fix #6684 (thanks @spritus)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@AlvaroEstradaDev @stevenwithaph @paxperscientiam @samme @actionmoon @rafael-lua @Byvire

- JavaScript
Published by photonstorm over 2 years ago

phaser - Phaser v3.70.0

Version 3.70.0 - Yotsuba - 10th November 2023

New Features - Round Pixels

All pixel rounding math is now handled on the GPU instead of on the CPU. This feature has now been enabled by default.

  • The Game Config roundPixels property is now true by default. This means that all Game Objects will be positioned and rendered with pixel-perfect precision, which is by far the most common use-case for Phaser games. This will prevent sub-pixelation when rendering at non-integer offsets and allows for smoother camera scrolling, especially at higher zoom scales. If you wish to disable this, you can do so by setting the roundPixels property in the Game Config to false. Note that only roundPixels has been set to true. The pixelArt property remains false. So if you're creating a pixel-art style game, please still enable this in your config.
  • All of the core vertex shaders, including Multi, Single and Mobile now have a new uniform called uRoundPixels which is set in all of the corresponding pipelines. This means that all pixel rounding calculations are now done on the GPU instead of the CPU, which can save a lot of math in intensive games.
  • CanvasRenderer.batchSprite has been updated to correctly use the Camera roundPixels property and apply it to the drawImage call.
  • Camera.preRender will no longer round the origin, follow coordinates or scrollX/Y coordinates. It will still round the World view.
  • The MultiPipeline.batchSprite method (which is also used by the Single Pipeline and Mobile Pipeline) will no longer use roundPixels when calculating the quad vertex data. It also won't apply it to any of the sprite values. This is all now handled in the shader directly.
  • TransformMatrix.setQuad no longer uses an anonymous function for roundPixels, which will help with performance.
  • The TransformMatrix.setQuad method signature has changed slightly. The roundPixels parameter is now optional and defaults to false. Previously, you always had to set it.

New Features - Texture Packer Nine Slice Support

The new version of Texture Packer (v7.1.0) and above will now allow you to export scale9 sprite data in your Phaser 3 Atlas JSON. This allows you to create Nine Slice Sprites directly from the data, without having to specify the border sizes directly in your code. To use this feature, simply edit the sprite in Texture Packer, enable the 'scale9' checkbox and then drag the guides as required. When you export the atlas, the JSON will contain the new scale9 object, which Phaser will parse and use when creating Nine Slice Game Objects.

  • You can now create a NineSlice Game Object without specifying a width or height for it. If you do this, it will use the size of the texture frame instead.
  • The NineSlice Game Object will now check to see if its associated Frame has any scale9 data set, and if so this is now used automatically to populate all of the border values.
  • The NineSlice.setSlices method has a new optional boolean parameter skipScale9 which will allow you to set the border values of the Nine Slice directly, even if its Frame has associated scale9 data
  • Frame.setScale9 is a new method that allows you to set the scale9 data associated with the given Frame. This is used internally by the Texture Packer parsers, but can also be called directly.
  • Frame.scale9 is a new read-only boolean property that returns true if the Frame has scale9 data associated with it.
  • Frame.is3Slice is a new read-only boolean property that returns true if the Frame has scale9 data associated with it that is 3-slice instead of 9-slice.
  • The JSONHash texture parser will now check for scale9 data in the JSON and if found, set it via the Frame.setScale9 method.
  • The JSONArray texture parser will now check for scale9 data in the JSON and if found, set it via the Frame.setScale9 method.

New Features - Arcade Physics

  • Arcade Physics Bodies have a new method called setDirectControl which toggles a new boolean property directControl. When enabled (it's false by default) it means the Body will calculate its velocity based on its change in position compared to the previous frame. This allows you to directly move a Body around the physics world by just changing its position, without having to use acceleration or velocity. This is useful if you want to move it via a Tween, or follow a Pointer, or a Path. Because its velocity is calculated based on this movement it will still resolve collisions with other bodies, imparting velocity to them as usual.
  • Arcade Physics Bodies have a new property called slideFactor. This is a Vector2 that controls how much velocity is retained by a Body after it has been pushed by another Body. The default value is 1, which means it retains all of its velocity. If set to zero, it will retain none of it. This allows you to create a Body that can be pushed around without imparting any velocity to it.
  • Body.setSlideFactor is a new method that sets the Body's slideFactor property.
  • The Arcade Physics World has a new method nextCategory which will create a new collision category and return it. You can define up to 32 unique collision categories per world.
  • Arcade Physics Bodies have two new properties: collisionCategory and collisionMask. These allow you to set a specific collision category and list of categories the body will collide with. This allows for fine-grained control over which bodies collide with which others. The default is that all bodies collide with all others, just like before.
  • setCollisionCategory is a new method available on Arcade Physics Bodies that allows you to set the collision category of the body. It's also available on Arcade Sprites, Images, Tilemap Layers, Groups and Static Groups directly.
  • setCollidesWith is a new method available on Arcade Physics Bodies that allows you to set which collision categories the body should collide with. It's also available on Arcade Sprites, Images, Tilemap Layers, Groups and Static Groups directly.
  • resetCollision is a new method available on Arcade Physics Bodies that allows you to reset the collision category and mask to their defaults. It's also available on Arcade Sprites, Images, Tilemap Layers, Groups and Static Groups directly.

The default is as before: all bodies collide with each other. However, by using the categories you now have much more fine-grained control over which objects collide together, or not. They are filtered out at the top-level, meaning you can have a Sprite set to not collide with a Physics Group and it will skip checking every single child in the Group, potentially saving a lot of processing time.

The new collision categories are used automatically by either directly calling the collide or overlap methods, or by creating a Collider object. This allows you to use far less colliders than you may have needed previously and skip needing to filter the pairs in the collision handlers.

New Features - FX Updates and Fixes

You can now set in your game config two new boolean properties that control if the built-in FX are enabled, or not. If you don't need to use the FX then disabling these will help save on texture memory and will compile less shaders, which can help with startup time. These are single-set flags, you cannot toggle them after the game has booted.

  • disablePreFX set this to true in your game config to disable the creation and use of Pre FX on all Game Objects.
  • disablePostFX set this to true in your game config to disable the creation and use of Post FX on all Game Objects.
  • The PipelineManager will now delay the creation of the FX Pipelines until its boot method, using these config values to determine if it should proceed.
  • The PipelineManager.renderTargets array will no longer be pre-populated if you disable Pre FX, saving on texture memory.
  • FX.Circle.backgroundAlpha is a new property that allows you to set the amount of the alpha of the background color in the Circle FX (thanks @rexrainbow)
  • PostFXPipeline.bootFX is a new method, which is the previous boot method but renamed. This is no longer called from the constructor, but instead when the Post FX Pipeline is activated by the Pipeline Manager. This means that the resources the Post FX requires, such as creating Render Targets and shaders, is delayed until the FX is actually used, saving on memory.
  • The PostFXPipeline will now set autoResize to true on all of its RenderTarget instances. This fixes an issue where the PostFXPipeline would not resize the render targets when the game size changed, causing them to become out of sync with the game canvas. Fix #6503 (thanks @Waclaw-I)
  • FX.Blur didn't set the quality parameter to its property, meaning it wasn't applied in the shader, causing it to always use a Low Blur quality (unless modified post-creation).
  • The BlurFXPipeline didn't bind the quality of shader specified in the controller, meaning it always used the Low Blur shader, regardless of what the FX controller asked for.
  • The FXBlurLow fragment shader didn't have the offset uniform. This is now passed in and applied to the resulting blur, preventing it from creating 45 degree artifacts (thanks Wayfinder)
  • Fixed an issue in the way the Tilemap WebGL Renderer would call batchTexture that meant if you applied a PostFX to a Tilemap Layer it would apply the fx for every single tile in the layer, instead of just once per layer. In a simple map this fix has reduced draw calls from over 12,000 to just 52, and it no longer matters how many tiles are on the layer, the cost of applying the FX is consistent regardless.

New Features

  • Text.setRTL is a new method that allows you to set a Text Game Object as being rendered from right-to-left, instead of the default left to right (thanks @rexrainbow)
  • Physics.Arcade.World.singleStep is a new method that will advance the Arcade Physics World simulation by exactly 1 step (thanks @monteiz)
  • Tilemaps.ObjectLayer.id is a new property that returns the ID of the Object Layer, if specified within Tiled, or zero otherwise. You can now access the unique layer ID of Tiled layers if the event a map doesn't have unique layer names (thanks @rui-han-crh)
  • Tilemaps.LayerData.id is a new property that returns the ID of the Data Layer, if specified within Tiled, or zero otherwise (thanks @rui-han-crh)
  • Text.setLetterSpacing is a new method and Text.letterSpacing is the related property that allows you to set the spacing between each character of a Text Game Object. The value can be either negative or positive, causing the characters to get closer or further apart. 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 (thanks @Ariorh1337)
  • ParticleEmitter.clearDeathZones is a new method that will clear all previously created Death Zones from a Particle Emitter (thanks @rexrainbow)
  • ParticleEmitter.clearEmitZones is a new method that will clear all previously created Emission Zones from a Particle Emitter (thanks @rexrainbow)
  • The GameObject.setTexture method has 2 new optional parameters: updateSize and updateOrigin, which are both passed to the setFrame method and allows you to control if the size and origin of the Game Object should be updated when the texture is set (thanks @Trissolo)
  • Both the Animation Config and the Play Animation Config allow you to set a new boolean property randomFrame. This is false by default, but if set, it will pick a random frame from the animation when it starts playback. This allows for much more variety in groups of sprites created at the same time, using the same animation. This is also reflected in the new Animation.randomFrame and AnimationState.randomFrame properties.
  • You can now use a Phaser.Types.Animations.PlayAnimationConfig object in the anims property of the ParticleEmitter configuration object. This gives you far more control over what happens to the animation when used by particles, including setting random start frames, repeat delays, yoyo, etc. Close #6478 (thanks @michalfialadev)
  • TilemapLayer.setTintFill is a new method that will apply a fill-based tint to the tiles in the given area, rather than an additive-based tint, which is what the setTint method uses.
  • Tile.tintFill is a new boolean property that controls if the tile tint is additive or fill based. This is used in the TilemapLayerWebGLRenderer function.
  • RenderTarget.willResize is a new method that will return true if the Render Target will be resized as a result of the new given width and height values.
  • Structs.Map.setAll is a new method that allows you to pass an array of elements to be set into the Map. This is a chainable method.
  • When creating a TimelineEvent you can now set a new optional callback: if. If set, this callback is invoked at the start of the TimelineEvent. If it returns true, then the rest of the event is processed (i.e. tweens started, sound played, etc) otherwise the event is skipped. This allows you to create conditional events within a Timeline.
  • Geom.Line.setFromObjects is a new method that will set the Line start and end points to match those of the two given objects, which can be Game Objects, or anything Vector2-like (thanks @Trissolo)

Updates

  • The WebAudioSoundManager will now bind the body to the removeEventListener method, if it exists, to prevent memory leaks (thanks @wjaykim)
  • The AnimationManager.globalTimeScale property is now applied to all Game Objects using the Animation component, allowing you to globally speed-up or slow down all animating objects (thanks @TJ09)
  • The Rope Game Object now calls initPostPipeline allowing you to use Post FX directly on it, such as glow, blur, etc. Fix #6550 (thanks @rexrainbow)
  • The Tween.stop method will now check to see if Tween.parent is set. If not, it won't try to set a pending removal state or dispatch an event, which should help guard against errors where Tween.stop is called by mistake on already destroyed tweens (thanks @orcomarcio)
  • The Tween.remove method will now check to see if Tween.parent exists before trying to remove it from the parent. This should help guard against errors where Tween.remove is called by mistake on already removed or destroyed tweens. Fix #6539 (thanks @orcomarcio)
  • Particle.alpha is now clamped to the range 0 to 1 within the update method, preventing it from going out of range. Fix #6551 (thanks @orcomarcio)
  • Math.Wrap has been reverted to the previous version. Fix #6479 (thanks @EmilSV)
  • The Graphics Game Object will now set a default line and fill style to fully transparent and black. This prevents issues where a Graphics object would render with a color set in other Shape Game Objects if it had been drawn to and no style was previous set (thanks Whitesmith)
  • The WebGLRenderer will now validate that the mipmapFilter property in the Game Config is a valid mipmap before assigning it.
  • A small amount of unused code has been removed from the Polygon.setTo method (thanks @Trissolo)
  • The WebGLRenderer.deleteFramebuffer method has been updated so it now tests for the existence of a COLOR and DEPTHSTENCIL attachments, and if found, removes the bindings and deletes the stencil buffer. The code that previously deleted the `RENDERERBUFFERBINDING` has also been removed to avoid side-effects.
  • If you make a Mesh Game Object interactive, it will now bind to the scope of the Mesh and uses the current faces in the hit area callback, rather than the faces as defined when the Mesh was made interactive. This will help keep the input in sync with a potentially changing Mesh structure (thanks @rexrainbow)
  • iOS and any browser identifying as AppleWebKit will now set the Device.es2019 flag to true. This causes Phaser to use the native array Stable Sort. This fixes an issue where overlapping particles could flicker on iOS. Fix #6483 (thanks @mattkelliher @spayton)
  • The Text.dirty Game Object property has been removed. It wasn't used internally at all, so was just adding confusion and using space.
  • The Request Video Frame polyfill will now check first to see if the browser supports HTMLVideoElement before trying to inspect its prototype. This should help in non-browser environments.
  • Plane.originX and originY are two new read-only properties that return the origin of the Plane, which is always 0.5 (thanks @rexrainbow)
  • The LoaderPlugin will now call removeAllListeners() as part of its shutdown method, which will clear any event listeners bound to a Loader instance of the Scene, during the Scene shutdown. Fix #6633 (thanks @samme)
  • SetCollisionObject is a new function that Arcade Physics bodies use internally to create and reset their ArcadeBodyCollision data objects.
  • DynamicTexture.setFromRenderTarget is a new method that syncs the internal Frame and TextureSource GL textures with the Render Target GL textures.
  • When a framebuffer is deleted, it now sets its renderTexture property to undefined to ensure the reference is cleared.
  • TransformMatrix.setToContext will now use setTransform(this) as 'this' is an equivalent object that this method can natively take.
  • Optimized WebGLRenderer.setTextureFilter so it no longer uses a temporary array for the filter mode.
  • The MultiPipeline.batchTexture method has a new optional boolean parameter skipPrePost that will force the call to ignore calling the preBatch and postBatch Pipeline Manager methods for the Game Object. This allows you to skip the overhead of calling them if you know you don't need them.
  • The tint property can now act as a getter and a setter, where-as previously it was only a setter. Reading this property returns the equivalent of the tintTopLeft value (thanks @rexrainbow)
  • ParticleEmitter.addDeathZone now returns an array of the Death Zone instances created, rather than just a single zone. This makes it functionally the same as addEmitZone (thanks @AlvaroEstradaDev)
  • The GameObjects.Layer.add method is now chainable (thanks @rexrainbow)
  • The GameObjects.Layer.remove and removeAll methods are now chainable and have a new optional boolean parameter destroyChild, which will destroy the Game Objects removed from the Layer (thanks @rexrainbow)
  • If a Game Object is destroyed, it will now automatically be removed from the Layer it was in, if any (thanks @rexrainbow)
  • Curves.Path.defaultDivisions is a new property that holds the default number of divisions to split the Path in to (thanks @AlvaroEstradaDev)
  • The Curves.Path.getPoints method has a new optional parameter stepRate which allows you to set the distance between points on the curve, and defaults to defaultDivisions (thanks @AlvaroEstradaDev)
  • The Timeline class will now emit the new Phaser.Time.Events#COMPLETE event when it completes. It will also no longer process its update method once the Timeline has completed (thanks @rexrainbow)
  • The BaseSound.destroy method will now call BaseSound.stop which will reset the isPlaying and other flags. Fix #6645 (thanks @rexrainbow)
  • The RandomDataGenerator#weightedPick method will no longer under-sample the first and last elements in the given array, leading to better distribution of results. Fix #6562 (thanks @wayfinder @shy @samme)
  • During Game.runDestroy it will now check for this.domContainer.parentNode before trying to remove it, preventing errors if the DOM Container has already been removed. Fix #6559 (thanks @orcomarcio)
  • The Game instance will now boot the new SYSTEM_READY event, which indicates that the internal Scene System has been created by the Scene Manager and is ready for use. The Texture Manager now listens for this event in order to create the stamp Image. This fixes an issue where the stamp would throw a run-time error if the game didn't feature a preload function. Fix #6616 (thanks @rexrainbow)

Bug Fixes

  • Particle.scaleY would always be set to the scaleX value, even if given a different one within the config. It will now use its own value correctly.
  • Array.Matrix.RotateLeft was missing the total parameter, which controls how many times to rotate the matrix.
  • Array.Matrix.RotateRight was missing the total parameter, which controls how many times to rotate the matrix.
  • Array.Matrix.TranslateMatrix didn't work with any translation values above 1 due to missing parameters in RotateLeft and RotateRight
  • The Tilemap.createFromObjects method wouldn't always copy custom properties to the target objects or Data Manager. Fix #6391 (thanks @samme @paxperscientiam)
  • The scale.min and scale.max width and height properties in Game Config were ignored by the Game constructor, which was expecting minWidth and minHeight. This now matches the documentation. Fix #6501 (thanks @NikitaShpanko @wpederzoli)
  • Due to a copy-paste bug, the Actions.GetLast function had the same code as the GetFirst function. It now does what you'd expect it to do. Fix #6513 (thanks @dmokel)
  • The TilemapLayer.PutTileAt method would use an incorrect local GID if the Tilemap Layer wasn't using all available tilesets. Fix #5931 (thanks @christianvoigt @wjaykim)
  • The TextureManager.addSpriteSheet method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @charlieschwabacher)
  • The HexagonalCullBounds function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The HexagonalGetTileCorners function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The HexagonalTileToWorldXY function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The BitmapText Game Object will now reset the WebGL Texture unit on flush, which fixes an issue of a flush happening part-way during the rendering a BitmapText (thanks @EmilSV)
  • When using interpolation for a Particle Emitter operation, such as: x: { values: [ 50, 500, 200, 800 ] } it would fail to set the final value unless you specified the interpolation property as well. It now defaults to linear if not given. Fix #6551 (thanks @orcomarcio)
  • The Matter Physics ignoreGravity boolean is now checked during the Matter Engine internal functions, allowing this property to now work again. Fix #6473 (thanks @peer2p)
  • Group.createFromConfig will now check to see if the config contains either internalCreateCallback or internalRemoveCallback and set them accordingly. This fixes an issue where the callbacks would never be set if specified in an array of single configuration objects. Fix #6519 (thanks @samme)
  • PhysicsGroup will now set the classType and null the config when an array of single configuration objects is given in the constructor. Fix #6519 (thanks @samme)
  • The PathFollower.pathUpdate method will now check if the tween property has a valid data component before running the update. This prevents a call to PathFollower.stopFollow from throwing a Cannot read properties of null (reading '0') error as it tried to do a single update post stop. Fix #6508 (thanks @francois-dibulo)
  • Added missing parameter to some function calls in Structs.ProcessQueue#add (thanks @Trissolo)
  • Tile was incorrectly using the Alpha Game Object component, instead of the AlphaSingle component, which meant although the methods implied you could set a different alpha per tile corner, it was never reflected in the rendering. It has now been updated to use just the single alpha value. Fix #6594 (thanks @jcoppage)
  • The TextureManager.addAtlasJSONArray method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addAtlasJSONHash method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addAtlasXML method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addUnityAtlas method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • DynamicTexture.preDestroy was never called, leading to an accumulation of framebuffers in memory. This method has now been renamed to destroy and cleans all references correctly.
  • If you gave the width or height in the Game Config object as a string it would multiply the value given by the parent size, often leading to a huge game canvas, or causing WebGL errors as it tried to create a texture larger than the GPU could handle. This has now been strengthened. If you give a string with a % at the end, it works as before, i.e. "100%" or "50%" to set the scale based on the parent. If you don't include the %, or use another unit, such as "800px" it will now be treated as a fixed value, not a percentage.
  • The ParticleEmitterWebGLRenderer has been refactored so that the particle.frame is used as the source of the glTexture used in the batch and also if a new texture unit is required. This fixes issues where a Particle Emitter would fail to use the correct frame from a multi-atlas texture. Fix #6515 (thanks @Demeno)
  • StaticBody.setSize will now check to see if the body has a Game Object or not, and only call getCenter and the frame sizes if it has. This fixes a bug where calling physics.add.staticBody would throw an error if you provided a width and height. Fix #6630 (thanks @Legend-Master)
  • The DynamicTexture.fill method will now correctly draw the fill rectangle if the width and height are provided in WebGL, where-as before it would assume the y axis started from the bottom-left instead of top-left. Fix #6615 (thanks @rexrainbow)
  • Calling the Line.setLineWidth method on the Line Shape Game Object would result in a line with double the thickness it should have had in WebGL. In Canvas it was the correct width. Both renderers now match. Fix #6604 (thanks @AlvaroNeuronup)
  • The DynamicTexture was leaking memory by leaving a WebGLTexture in memory when its setSize method was called. This happens automatically on instantiation, meaning that if you created DynamicTextures and then destroyed them frequently, memory would continue to increase (thanks David)
  • DynamicTexture.width and height were missing from the class definition, even though they were set and used internally. They're now exposed as read-only properties.
  • The BitmapMask wouldn't correctly set the gl viewport when binding, which caused the mask to distort in games where the canvas resizes from its default. Fix #6527 (thanks @rexrainbow)
  • The Geom.Intersects.GetLineToPoints function has been fixed to correct an oversight where the for loop prevented an intersection test between the given line and the line segment between the first and last point. Fix #6467 (thanks @Trissolo @Abspirit)
  • The MultiAtlas File Loader didn't prepend the Loader.prefix if set. This now forms part of the key, leading to the correct keys used for the Texture Manager. Fix #6614 (thanks @machineman1357)
  • There was an issue when loading Normal Maps with Sprite Sheets. Often, if the normal map image completed loading before the sprite sheet, it would cause it to be incorrectly added to the Texture Manager, resulting in broken frames. Now, regardless of the load order, the sprite sheet is added with its normal map correctly together. Fix #6491 (thanks @dreasgrech @PaulB-H @samme)
  • The TextureSource.setFilter method will now check to see if renderer is defined before accessing its gl property. This avoids Phaser crashing if you're in headless mode and set anti-aliasing to false in the game config. Fix #6663 (thanks @moufmouf)
  • SpineGameObject.setSkeletonFromJSON has been fixed so it now passes the parameters in the correct order to the setSkeleton method. Fix #6585 (thanks @machineman1357)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@AlvaroEstradaDev @emadkhezri @gohack0322 @johnhyde @julescubtree @neki-dev @paxperscientiam @samme

- JavaScript
Published by photonstorm over 2 years ago

phaser - Phaser 3.61.0 Beta 4

New Features - Arcade Physics

  • Arcade Physics Bodies have a new method called setDirectControl which toggles a new boolean property directControl. When enabled (it's false by default) it means the Body will calculate its velocity based on its change in position compared to the previous frame. This allows you to directly move a Body around the physics world by just changing its position, without having to use acceleration or velocity. This is useful if you want to move it via a Tween, or follow a Pointer, or a Path. Because its velocity is calculated based on this movement it will still resolve collisions with other bodies, imparting velocity to them as usual.
  • Arcade Physics Bodies have a new property called slideFactor. This is a Vector2 that controls how much velocity is retained by a Body after it has been pushed by another Body. The default value is 1, which means it retains all of its velocity. If set to zero, it will retain none of it. This allows you to create a Body that can be pushed around without imparting any velocity to it.
  • Body.setSlideFactor is a new method that sets the Body's slideFactor property.
  • The Arcade Physics World has a new method nextCategory which will create a new collision category and return it. You can define up to 32 unique collision categories per world.
  • Arcade Physics Bodies have two new properties: collisionCategory and collisionMask. These allow you to set a specific collision category and list of categories the body will collide with. This allows for fine-grained control over which bodies collide with which others. The default is that all bodies collide with all others, just like before.
  • setCollisionCategory is a new method available on Arcade Physics Bodies that allows you to set the collision category of the body. It's also available on Arcade Sprites, Images, Tilemap Layers, Groups and Static Groups directly.
  • setCollidesWith is a new method available on Arcade Physics Bodies that allows you to set which collision categories the body should collide with. It's also available on Arcade Sprites, Images, Tilemap Layers, Groups and Static Groups directly.
  • resetCollision is a new method available on Arcade Physics Bodies that allows you to reset the collision category and mask to their defaults. It's also available on Arcade Sprites, Images, Tilemap Layers, Groups and Static Groups directly.

The default is as before: all bodies collide with each other. However, by using the categories you now have much more fine-grained control over which objects collide together, or not. They are filtered out at the top-level, meaning you can have a Sprite set to not collide with a Physics Group and it will skip checking every single child in the Group, potentially saving a lot of processing time.

The new collision categories are used automatically by either directly calling the collide or overlap methods, or by creating a Collider object. This allows you to use far less colliders than you may have needed previously and skip needing to filter the pairs in the collision handlers.

New Features

  • Text.setRTL is a new method that allows you to set a Text Game Object as being rendered from right-to-left, instead of the default left to right (thanks @rexrainbow)
  • FX.Circle.backgroundAlpha is a new property that allows you to set the amount of the alpha of the background color in the Circle FX (thanks @rexrainbow)
  • Physics.Arcade.World.singleStep is a new method that will advance the Arcade Physics World simulation by exactly 1 step (thanks @monteiz)
  • Tilemaps.ObjectLayer.id is a new property that returns the ID of the Object Layer, if specified within Tiled, or zero otherwise. You can now access the unique layer ID of Tiled layers if the event a map doesn't have unique layer names (thanks @rui-han-crh)
  • Tilemaps.LayerData.id is a new property that returns the ID of the Data Layer, if specified within Tiled, or zero otherwise (thanks @rui-han-crh)
  • Text.setLetterSpacing is a new method and Text.lineSpacing is the related property that allows you to set the spacing between each character of a Text Game Object. The value can be either negative or positive, causing the characters to get closer or further apart. 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 (thanks @Ariorh1337)
  • ParticleEmitter.clearDeathZones is a new method that will clear all previously created Death Zones from a Particle Emitter (thanks @rexrainbow)
  • ParticleEmitter.clearEmitZones is a new method that will clear all previously created Emission Zones from a Particle Emitter (thanks @rexrainbow)
  • The GameObject.setTexture method has 2 new optional parameters: updateSize and updateOrigin, which are both passed to the setFrame method and allows you to control if the size and origin of the Game Object should be updated when the texture is set (thanks @Trissolo)
  • Both the Animation Config and the Play Animation Config allow you to set a new boolean property randomFrame. This is false by default, but if set, it will pick a random frame from the animation when it starts playback. This allows for much more variety in groups of sprites created at the same time, using the same animation. This is also reflected in the new Animation.randomFrame and AnimationState.randomFrame properties.
  • You can now use a Phaser.Types.Animations.PlayAnimationConfig object in the anims property of the ParticleEmitter configuration object. This gives you far more control over what happens to the animation when used by particles, including setting random start frames, repeat delays, yoyo, etc. Close #6478 (thanks @michalfialadev)
  • TilemapLayer.setTintFill is a new method that will apply a fill-based tint to the tiles in the given area, rather than an additive-based tint, which is what the setTint method uses.
  • Tile.tintFill is a new boolean property that controls if the tile tint is additive or fill based. This is used in the TilemapLayerWebGLRenderer function.

Updates

  • The WebAudioSoundManager will now bind the body to the removeEventListener method, if it exists, to prevent memory leaks (thanks @wjaykim)
  • The AnimationManager.globalTimeScale property is now applied to all Game Objects using the Animation component, allowing you to globally speed-up or slow down all animating objects (thanks @TJ09)
  • The Rope Game Object now calls initPostPipeline allowing you to use Post FX directly on it, such as glow, blur, etc. Fix #6550 (thanks @rexrainbow)
  • The Tween.stop method will now check to see if Tween.parent is set. If not, it won't try to set a pending removal state or dispatch an event, which should help guard against errors where Tween.stop is called by mistake on already destroyed tweens (thanks @orcomarcio)
  • The Tween.remove method will now check to see if Tween.parent exists before trying to remove it from the parent. This should help guard against errors where Tween.remove is called by mistake on already removed or destroyed tweens. Fix #6539 (thanks @orcomarcio)
  • Particle.alpha is now clamped to the range 0 to 1 within the update method, preventing it from going out of range. Fix #6551 (thanks @orcomarcio)
  • Math.Wrap has been reverted to the previous version. Fix #6479 (thanks @EmilSV)
  • The Graphics Game Object will now set a default line and fill style to fully transparent and black. This prevents issues where a Graphics object would render with a color set in other Shape Game Objects if it had been drawn to and no style was previous set (thanks Whitesmith)
  • The WebGLRenderer will now validate that the mipmapFilter property in the Game Config is a valid mipmap before assigning it.
  • A small amount of unused code has been removed from the Polygon.setTo method (thanks @Trissolo)
  • The WebGLRenderer.deleteFramebuffer method has been updated so it now tests for the existence of a COLOR and DEPTHSTENCIL attachments, and if found, removes the bindings and deletes the stencil buffer. The code that previously deleted the `RENDERERBUFFERBINDING` has also been removed to avoid side-effects.
  • If you make a Mesh Game Object interactive, it will now bind to the scope of the Mesh and uses the current faces in the hit area callback, rather than the faces as defined when the Mesh was made interactive. This will help keep the input in sync with a potentially changing Mesh structure (thanks @rexrainbow)
  • iOS and any browser identifying as AppleWebKit will now set the Device.es2019 flag to true. This causes Phaser to use the native array Stable Sort. This fixes an issue where overlapping particles could flicker on iOS. Fix #6483 (thanks @mattkelliher @spayton)
  • The Text.dirty Game Object property has been removed. It wasn't used internally at all, so was just adding confusion and using space.
  • The Request Video Frame polyfill will now check first to see if the browser supports HTMLVideoElement before trying to inspect its prototype. This should help in non-browser environments.
  • Plane.originX and originY are two new read-only properties that return the origin of the Plane, which is always 0.5 (thanks @rexrainbow)
  • The LoaderPlugin will now call removeAllListeners() as part of its shutdown method, which will clear any event listeners bound to a Loader instance of the Scene, during the Scene shutdown. Fix #6633 (thanks @samme)
  • SetCollisionObject is a new function that Arcade Physics bodies use internally to create and reset their ArcadeBodyCollision data objects.
  • DynamicTexture.setFromRenderTarget is a new method that syncs the internal Frame and TextureSource GL textures with the Render Target GL textures.
  • When a framebuffer is deleted, it now sets its renderTexture property to undefined to ensure the reference is cleared.

Bug Fixes

  • The PostFXPipeline will now set autoResize to true on all of its RenderTarget instances. This fixes an issue where the PostFXPipeline would not resize the render targets when the game size changed, causing them to become out of sync with the game canvas. Fix #6503 (thanks @Waclaw-I)
  • Particle.scaleY would always be set to the scaleX value, even if given a different one within the config. It will now use its own value correctly.
  • Array.Matrix.RotateLeft was missing the total parameter, which controls how many times to rotate the matrix.
  • Array.Matrix.RotateRight was missing the total parameter, which controls how many times to rotate the matrix.
  • Array.Matrix.TranslateMatrix didn't work with any translation values above 1 due to missing parameters in RotateLeft and RotateRight
  • FX.Blur didn't set the quality parameter to its property, meaning it wasn't applied in the shader, causing it to always use a Low Blur quality (unless modified post-creation).
  • The BlurFXPipeline didn't bind the quality of shader specified in the controller, meaning it always used the Low Blur shader, regardless of what the FX controller asked for.
  • The FXBlurLow fragment shader didn't have the offset uniform. This is now passed in and applied to the resulting blur, preventing it from creating 45 degree artifacts (thanks Wayfinder)
  • The Tilemap.createFromObjects method wouldn't always copy custom properties to the target objects or Data Manager. Fix #6391 (thanks @samme @paxperscientiam)
  • The scale.min and scale.max width and height properties in Game Config were ignored by the Game constructor, which was expecting minWidth and minHeight. This now matches the documentation. Fix #6501 (thanks @NikitaShpanko @wpederzoli)
  • Due to a copy-paste bug, the Actions.GetLast function had the same code as the GetFirst function. It now does what you'd expect it to do. Fix #6513 (thanks @dmokel)
  • The TilemapLayer.PutTileAt method would use an incorrect local GID if the Tilemap Layer wasn't using all available tilesets. Fix #5931 (thanks @christianvoigt @wjaykim)
  • The TextureManager.addSpriteSheet method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @charlieschwabacher)
  • The HexagonalCullBounds function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The HexagonalGetTileCorners function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The HexagonalTileToWorldXY function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The BitmapText Game Object will now reset the WebGL Texture unit on flush, which fixes an issue of a flush happening part-way during the rendering a BitmapText (thanks @EmilSV)
  • When using interpolation for a Particle Emitter operation, such as: x: { values: [ 50, 500, 200, 800 ] } it would fail to set the final value unless you specified the interpolation property as well. It now defaults to linear if not given. Fix #6551 (thanks @orcomarcio)
  • The Matter Physics ignoreGravity boolean is now checked during the Matter Engine internal functions, allowing this property to now work again. Fix #6473 (thanks @peer2p)
  • Group.createFromConfig will now check to see if the config contains either internalCreateCallback or internalRemoveCallback and set them accordingly. This fixes an issue where the callbacks would never be set if specified in an array of single configuration objects. Fix #6519 (thanks @samme)
  • PhysicsGroup will now set the classType and null the config when an array of single configuration objects is given in the constructor. Fix #6519 (thanks @samme)
  • The PathFollower.pathUpdate method will now check if the tween property has a valid data component before running the update. This prevents a call to PathFollower.stopFollow from throwing a Cannot read properties of null (reading '0') error as it tried to do a single update post stop. Fix #6508 (thanks @francois-dibulo)
  • Added missing parameter to some function calls in Structs.ProcessQueue#add (thanks @Trissolo)
  • Tile was incorrectly using the Alpha Game Object component, instead of the AlphaSingle component, which meant although the methods implied you could set a different alpha per tile corner, it was never reflected in the rendering. It has now been updated to use just the single alpha value. Fix #6594 (thanks @jcoppage)
  • The TextureManager.addAtlasJSONArray method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addAtlasJSONHash method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addAtlasXML method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addUnityAtlas method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • DynamicTexture.preDestroy was never called, leading to an accumulation of framebuffers in memory. This method has now been renamed to destroy and cleans all references correctly.
  • If you gave the width or height in the Game Config object as a string it would multiply the value given by the parent size, often leading to a huge game canvas, or causing WebGL errors as it tried to create a texture larger than the GPU could handle. This has now been strengthened. If you give a string with a % at the end, it works as before, i.e. "100%" or "50%" to set the scale based on the parent. If you don't include the %, or use another unit, such as "800px" it will now be treated as a fixed value, not a percentage.
  • The ParticleEmitterWebGLRenderer has been refactored so that the particle.frame is used as the source of the glTexture used in the batch and also if a new texture unit is required. This fixes issues where a Particle Emitter would fail to use the correct frame from a multi-atlas texture. Fix #6515 (thanks @Demeno)
  • StaticBody.setSize will now check to see if the body has a Game Object or not, and only call getCenter and the frame sizes if it has. This fixes a bug where calling physics.add.staticBody would throw an error if you provided a width and height. Fix #6630 (thanks @Legend-Master)
  • The DynamicTexture.fill method will now correctly draw the fill rectangle if the width and height are provided in WebGL, where-as before it would assume the y axis started from the bottom-left instead of top-left. Fix #6615 (thanks @rexrainbow)
  • Calling the Line.setLineWidth method on the Line Shape Game Object would result in a line with double the thickness it should have had in WebGL. In Canvas it was the correct width. Both renderers now match. Fix #6604 (thanks @AlvaroNeuronup)
  • The DynamicTexture was leaking memory by leaving a WebGLTexture in memory when its setSize method was called. This happens automatically on instantiation, meaning that if you created DynamicTextures and then destroyed them frequently, memory would continue to increase (thanks David)
  • DynamicTexture.width and height were missing from the class definition, even though they were set and used internally. They're now exposed as read-only properties.
  • The BitmapMask wouldn't correctly set the gl viewport when binding, which caused the mask to distort in games where the canvas resizes from its default. Fix #6527 (thanks @rexrainbow)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @AlvaroEstradaDev @julescubtree @emadkhezri

- JavaScript
Published by photonstorm over 2 years ago

phaser - Phaser 3.61.0 Beta 3

New Features - Arcade Physics

  • Arcade Physics Bodies have a new property called slideFactor. This is a Vector2 that controls how much velocity is retained by a Body after it has been pushed by another Body. The default value is 1, which means it retains all of its velocity. If set to zero, it will retain none of it. This allows you to create a Body that can be pushed around without imparting any velocity to it.
  • Body.setSlideFactor is a new method that sets the Body's slideFactor property.
  • The Arcade Physics World has a new method nextCategory which will create a new collision category and return it. You can define up to 32 unique collision categories per world.
  • Arcade Physics Bodies have two new properties: collisionCategory and collisionMask. These allow you to set a specific collision category and list of categories the body will collide with. This allows for fine-grained control over which bodies collide with which others. The default is that all bodies collide with all others, just like before.
  • setCollisionCategory is a new method available on Arcade Physics Bodies that allows you to set the collision category of the body. It's also available on Arcade Sprites, Images, Tilemap Layers, Groups and Static Groups directly.
  • setCollidesWith is a new method available on Arcade Physics Bodies that allows you to set which collision categories the body should collide with. It's also available on Arcade Sprites, Images, Tilemap Layers, Groups and Static Groups directly.
  • resetCollision is a new method available on Arcade Physics Bodies that allows you to reset the collision category and mask to their defaults. It's also available on Arcade Sprites, Images, Tilemap Layers, Groups and Static Groups directly.

The default is as before: all bodies collide with each other. However, by using the categories you now have much more fine-grained control over which objects collide together, or not. They are filtered out at the top-level, meaning you can have a Sprite set to not collide with a Physics Group and it will skip checking every single child in the Group, potentially saving a lot of processing time.

The new collision categories are used automatically by either directly calling the collide or overlap methods, or by creating a Collider object. This allows you to use far less colliders than you may have needed previously and skip needing to filter the pairs in the collision handlers.

New Features

  • Text.setRTL is a new method that allows you to set a Text Game Object as being rendered from right-to-left, instead of the default left to right (thanks @rexrainbow)
  • FX.Circle.backgroundAlpha is a new property that allows you to set the amount of the alpha of the background color in the Circle FX (thanks @rexrainbow)
  • Physics.Arcade.World.singleStep is a new method that will advance the Arcade Physics World simulation by exactly 1 step (thanks @monteiz)
  • Tilemaps.ObjectLayer.id is a new property that returns the ID of the Object Layer, if specified within Tiled, or zero otherwise. You can now access the unique layer ID of Tiled layers if the event a map doesn't have unique layer names (thanks @rui-han-crh)
  • Tilemaps.LayerData.id is a new property that returns the ID of the Data Layer, if specified within Tiled, or zero otherwise (thanks @rui-han-crh)
  • Text.setLetterSpacing is a new method and Text.lineSpacing is the related property that allows you to set the spacing between each character of a Text Game Object. The value can be either negative or positive, causing the characters to get closer or further apart. 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 (thanks @Ariorh1337)
  • ParticleEmitter.clearDeathZones is a new method that will clear all previously created Death Zones from a Particle Emitter (thanks @rexrainbow)
  • ParticleEmitter.clearEmitZones is a new method that will clear all previously created Emission Zones from a Particle Emitter (thanks @rexrainbow)
  • The GameObject.setTexture method has 2 new optional parameters: updateSize and updateOrigin, which are both passed to the setFrame method and allows you to control if the size and origin of the Game Object should be updated when the texture is set (thanks @Trissolo)
  • Both the Animation Config and the Play Animation Config allow you to set a new boolean property randomFrame. This is false by default, but if set, it will pick a random frame from the animation when it starts playback. This allows for much more variety in groups of sprites created at the same time, using the same animation. This is also reflected in the new Animation.randomFrame and AnimationState.randomFrame properties.
  • You can now use a Phaser.Types.Animations.PlayAnimationConfig object in the anims property of the ParticleEmitter configuration object. This gives you far more control over what happens to the animation when used by particles, including setting random start frames, repeat delays, yoyo, etc. Close #6478 (thanks @michalfialadev)
  • TilemapLayer.setTintFill is a new method that will apply a fill-based tint to the tiles in the given area, rather than an additive-based tint, which is what the setTint method uses.
  • Tile.tintFill is a new boolean property that controls if the tile tint is additive or fill based. This is used in the TilemapLayerWebGLRenderer function.

Updates

  • The WebAudioSoundManager will now bind the body to the removeEventListener method, if it exists, to prevent memory leaks (thanks @wjaykim)
  • The AnimationManager.globalTimeScale property is now applied to all Game Objects using the Animation component, allowing you to globally speed-up or slow down all animating objects (thanks @TJ09)
  • The Rope Game Object now calls initPostPipeline allowing you to use Post FX directly on it, such as glow, blur, etc. Fix #6550 (thanks @rexrainbow)
  • The Tween.stop method will now check to see if Tween.parent is set. If not, it won't try to set a pending removal state or dispatch an event, which should help guard against errors where Tween.stop is called by mistake on already destroyed tweens (thanks @orcomarcio)
  • The Tween.remove method will now check to see if Tween.parent exists before trying to remove it from the parent. This should help guard against errors where Tween.remove is called by mistake on already removed or destroyed tweens. Fix #6539 (thanks @orcomarcio)
  • Particle.alpha is now clamped to the range 0 to 1 within the update method, preventing it from going out of range. Fix #6551 (thanks @orcomarcio)
  • Math.Wrap has been reverted to the previous version. Fix #6479 (thanks @EmilSV)
  • The Graphics Game Object will now set a default line and fill style to fully transparent and black. This prevents issues where a Graphics object would render with a color set in other Shape Game Objects if it had been drawn to and no style was previous set (thanks Whitesmith)
  • The WebGLRenderer will now validate that the mipmapFilter property in the Game Config is a valid mipmap before assigning it.
  • A small amount of unused code has been removed from the Polygon.setTo method (thanks @Trissolo)
  • The WebGLRenderer.deleteFramebuffer method has been updated so it now tests for the existence of a COLOR and DEPTHSTENCIL attachments, and if found, removes the bindings and deletes the stencil buffer. The code that previously deleted the `RENDERERBUFFERBINDING` has also been removed to avoid side-effects.
  • If you make a Mesh Game Object interactive, it will now bind to the scope of the Mesh and uses the current faces in the hit area callback, rather than the faces as defined when the Mesh was made interactive. This will help keep the input in sync with a potentially changing Mesh structure (thanks @rexrainbow)
  • iOS and any browser identifying as AppleWebKit will now set the Device.es2019 flag to true. This causes Phaser to use the native array Stable Sort. This fixes an issue where overlapping particles could flicker on iOS. Fix #6483 (thanks @mattkelliher @spayton)
  • The Text.dirty Game Object property has been removed. It wasn't used internally at all, so was just adding confusion and using space.
  • The Request Video Frame polyfill will now check first to see if the browser supports HTMLVideoElement before trying to inspect its prototype. This should help in non-browser environments.
  • Plane.originX and originY are two new read-only properties that return the origin of the Plane, which is always 0.5 (thanks @rexrainbow)
  • The LoaderPlugin will now call removeAllListeners() as part of its shutdown method, which will clear any event listeners bound to a Loader instance of the Scene, during the Scene shutdown. Fix #6633 (thanks @samme)
  • SetCollisionObject is a new function that Arcade Physics bodies use internally to create and reset their ArcadeBodyCollision data objects.
  • DynamicTexture.setFromRenderTarget is a new method that syncs the internal Frame and TextureSource GL textures with the Render Target GL textures.
  • When a framebuffer is deleted, it now sets its renderTexture property to undefined to ensure the reference is cleared.

Bug Fixes

  • The PostFXPipeline will now set autoResize to true on all of its RenderTarget instances. This fixes an issue where the PostFXPipeline would not resize the render targets when the game size changed, causing them to become out of sync with the game canvas. Fix #6503 (thanks @Waclaw-I)
  • Particle.scaleY would always be set to the scaleX value, even if given a different one within the config. It will now use its own value correctly.
  • Array.Matrix.RotateLeft was missing the total parameter, which controls how many times to rotate the matrix.
  • Array.Matrix.RotateRight was missing the total parameter, which controls how many times to rotate the matrix.
  • Array.Matrix.TranslateMatrix didn't work with any translation values above 1 due to missing parameters in RotateLeft and RotateRight
  • FX.Blur didn't set the quality parameter to its property, meaning it wasn't applied in the shader, causing it to always use a Low Blur quality (unless modified post-creation).
  • The BlurFXPipeline didn't bind the quality of shader specified in the controller, meaning it always used the Low Blur shader, regardless of what the FX controller asked for.
  • The FXBlurLow fragment shader didn't have the offset uniform. This is now passed in and applied to the resulting blur, preventing it from creating 45 degree artifacts (thanks Wayfinder)
  • The Tilemap.createFromObjects method wouldn't always copy custom properties to the target objects or Data Manager. Fix #6391 (thanks @samme @paxperscientiam)
  • The scale.min and scale.max width and height properties in Game Config were ignored by the Game constructor, which was expecting minWidth and minHeight. This now matches the documentation. Fix #6501 (thanks @NikitaShpanko @wpederzoli)
  • Due to a copy-paste bug, the Actions.GetLast function had the same code as the GetFirst function. It now does what you'd expect it to do. Fix #6513 (thanks @dmokel)
  • The TilemapLayer.PutTileAt method would use an incorrect local GID if the Tilemap Layer wasn't using all available tilesets. Fix #5931 (thanks @christianvoigt @wjaykim)
  • The TextureManager.addSpriteSheet method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @charlieschwabacher)
  • The HexagonalCullBounds function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The HexagonalGetTileCorners function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The HexagonalTileToWorldXY function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The BitmapText Game Object will now reset the WebGL Texture unit on flush, which fixes an issue of a flush happening part-way during the rendering a BitmapText (thanks @EmilSV)
  • When using interpolation for a Particle Emitter operation, such as: x: { values: [ 50, 500, 200, 800 ] } it would fail to set the final value unless you specified the interpolation property as well. It now defaults to linear if not given. Fix #6551 (thanks @orcomarcio)
  • The Matter Physics ignoreGravity boolean is now checked during the Matter Engine internal functions, allowing this property to now work again. Fix #6473 (thanks @peer2p)
  • Group.createFromConfig will now check to see if the config contains either internalCreateCallback or internalRemoveCallback and set them accordingly. This fixes an issue where the callbacks would never be set if specified in an array of single configuration objects. Fix #6519 (thanks @samme)
  • PhysicsGroup will now set the classType and null the config when an array of single configuration objects is given in the constructor. Fix #6519 (thanks @samme)
  • The PathFollower.pathUpdate method will now check if the tween property has a valid data component before running the update. This prevents a call to PathFollower.stopFollow from throwing a Cannot read properties of null (reading '0') error as it tried to do a single update post stop. Fix #6508 (thanks @francois-dibulo)
  • Added missing parameter to some function calls in Structs.ProcessQueue#add (thanks @Trissolo)
  • Tile was incorrectly using the Alpha Game Object component, instead of the AlphaSingle component, which meant although the methods implied you could set a different alpha per tile corner, it was never reflected in the rendering. It has now been updated to use just the single alpha value. Fix #6594 (thanks @jcoppage)
  • The TextureManager.addAtlasJSONArray method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addAtlasJSONHash method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addAtlasXML method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addUnityAtlas method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • DynamicTexture.preDestroy was never called, leading to an accumulation of framebuffers in memory. This method has now been renamed to destroy and cleans all references correctly.
  • If you gave the width or height in the Game Config object as a string it would multiply the value given by the parent size, often leading to a huge game canvas, or causing WebGL errors as it tried to create a texture larger than the GPU could handle. This has now been strengthened. If you give a string with a % at the end, it works as before, i.e. "100%" or "50%" to set the scale based on the parent. If you don't include the %, or use another unit, such as "800px" it will now be treated as a fixed value, not a percentage.
  • The ParticleEmitterWebGLRenderer has been refactored so that the particle.frame is used as the source of the glTexture used in the batch and also if a new texture unit is required. This fixes issues where a Particle Emitter would fail to use the correct frame from a multi-atlas texture. Fix #6515 (thanks @Demeno)
  • StaticBody.setSize will now check to see if the body has a Game Object or not, and only call getCenter and the frame sizes if it has. This fixes a bug where calling physics.add.staticBody would throw an error if you provided a width and height. Fix #6630 (thanks @Legend-Master)
  • The DynamicTexture.fill method will now correctly draw the fill rectangle if the width and height are provided in WebGL, where-as before it would assume the y axis started from the bottom-left instead of top-left. Fix #6615 (thanks @rexrainbow)
  • Calling the Line.setLineWidth method on the Line Shape Game Object would result in a line with double the thickness it should have had in WebGL. In Canvas it was the correct width. Both renderers now match. Fix #6604 (thanks @AlvaroNeuronup)
  • The DynamicTexture was leaking memory by leaving a WebGLTexture in memory when its setSize method was called. This happens automatically on instantiation, meaning that if you created DynamicTextures and then destroyed them frequently, memory would continue to increase (thanks David)
  • DynamicTexture.width and height were missing from the class definition, even though they were set and used internally. They're now exposed as read-only properties.
  • The BitmapMask wouldn't correctly set the gl viewport when binding, which caused the mask to distort in games where the canvas resizes from its default. Fix #6527 (thanks @rexrainbow)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @AlvaroEstradaDev @julescubtree @emadkhezri

- JavaScript
Published by photonstorm over 2 years ago

phaser - Phaser 3.61.0 Beta 2

New Features

  • Text.setRTL is a new method that allows you to set a Text Game Object as being rendered from right-to-left, instead of the default left to right (thanks @rexrainbow)
  • FX.Circle.backgroundAlpha is a new property that allows you to set the amount of the alpha of the background color in the Circle FX (thanks @rexrainbow)
  • Physics.Arcade.World.singleStep is a new method that will advance the Arcade Physics World simulation by exactly 1 step (thanks @monteiz)
  • Tilemaps.ObjectLayer.id is a new property that returns the ID of the Object Layer, if specified within Tiled, or zero otherwise. You can now access the unique layer ID of Tiled layers if the event a map doesn't have unique layer names (thanks @rui-han-crh)
  • Tilemaps.LayerData.id is a new property that returns the ID of the Data Layer, if specified within Tiled, or zero otherwise (thanks @rui-han-crh)
  • Text.setLetterSpacing is a new method and Text.lineSpacing is the related property that allows you to set the spacing between each character of a Text Game Object. The value can be either negative or positive, causing the characters to get closer or further apart. 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 (thanks @Ariorh1337)
  • ParticleEmitter.clearDeathZones is a new method that will clear all previously created Death Zones from a Particle Emitter (thanks @rexrainbow)
  • ParticleEmitter.clearEmitZones is a new method that will clear all previously created Emission Zones from a Particle Emitter (thanks @rexrainbow)
  • The GameObject.setTexture method has 2 new optional parameters: updateSize and updateOrigin, which are both passed to the setFrame method and allows you to control if the size and origin of the Game Object should be updated when the texture is set (thanks @Trissolo)
  • Both the Animation Config and the Play Animation Config allow you to set a new boolean property randomFrame. This is false by default, but if set, it will pick a random frame from the animation when it starts playback. This allows for much more variety in groups of sprites created at the same time, using the same animation. This is also reflected in the new Animation.randomFrame and AnimationState.randomFrame properties.
  • You can now use a Phaser.Types.Animations.PlayAnimationConfig object in the anims property of the ParticleEmitter configuration object. This gives you far more control over what happens to the animation when used by particles, including setting random start frames, repeat delays, yoyo, etc. Close #6478 (thanks @michalfialadev)

Updates

  • The WebAudioSoundManager will now bind the body to the removeEventListener method, if it exists, to prevent memory leaks (thanks @wjaykim)
  • The AnimationManager.globalTimeScale property is now applied to all Game Objects using the Animation component, allowing you to globally speed-up or slow down all animating objects (thanks @TJ09)
  • The Rope Game Object now calls initPostPipeline allowing you to use Post FX directly on it, such as glow, blur, etc. Fix #6550 (thanks @rexrainbow)
  • The Tween.stop method will now check to see if Tween.parent is set. If not, it won't try to set a pending removal state or dispatch an event, which should help guard against errors where Tween.stop is called by mistake on already destroyed tweens (thanks @orcomarcio)
  • The Tween.remove method will now check to see if Tween.parent exists before trying to remove it from the parent. This should help guard against errors where Tween.remove is called by mistake on already removed or destroyed tweens. Fix #6539 (thanks @orcomarcio)
  • Particle.alpha is now clamped to the range 0 to 1 within the update method, preventing it from going out of range. Fix #6551 (thanks @orcomarcio)
  • Math.Wrap has been reverted to the previous version. Fix #6479 (thanks @EmilSV)
  • The Graphics Game Object will now set a default line and fill style to fully transparent and black. This prevents issues where a Graphics object would render with a color set in other Shape Game Objects if it had been drawn to and no style was previous set (thanks Whitesmith)
  • The WebGLRenderer will now validate that the mipmapFilter property in the Game Config is a valid mipmap before assigning it.
  • A small amount of unused code has been removed from the Polygon.setTo method (thanks @Trissolo)
  • The WebGLRenderer.deleteFramebuffer method has been updated so it now tests for the exitennce of a COLOR and DEPTHSTENCIL attachments, and if found, removes the bindings and deletes the stencil buffer. The code that previously deelted the `RENDERERBUFFERBINDING` has also been removed to avoid side-effects.
  • If you make a Mesh Game Object interactive, it will now bind to the scope of the Mesh and uses the current faces in the hit area callback, rather than the faces as defined when the Mesh was made interactive. This will help keep the input in sync with a potentially changing Mesh structure (thanks @rexrainbow)
  • iOS and any browser identifying as AppleWebKit will now set the Device.es2019 flag to true. This causes Phaser to use the native array Stable Sort. This fixes an issue where overlapping particles could flicker on iOS. Fix #6483 (thanks @mattkelliher @spayton)

Bug Fixes

  • The PostFXPipeline will now set autoResize to true on all of its RenderTarget instances. This fixes an issue where the PostFXPipeline would not resize the render targets when the game size changed, causing them to become out of sync with the game canvas. Fix #6503 #6527 (thanks @Waclaw-I @rexrainbow)
  • Particle.scaleY would always be set to the scaleX value, even if given a different one within the config. It will now use its own value correctly.
  • Array.Matrix.RotateLeft was missing the total parameter, which controls how many times to rotate the matrix.
  • Array.Matrix.RotateRight was missing the total parameter, which controls how many times to rotate the matrix.
  • Array.Matrix.TranslateMatrix didn't work with any translation values above 1 due to missing parameters in RotateLeft and RotateRight
  • FX.Blur didn't set the quality parameter to its property, meaning it wasn't applied in the shader, causing it to always use a Low Blur quality (unless modified post-creation).
  • The BlurFXPipeline didn't bind the quality of shader specified in the controller, meaning it always used the Low Blur shader, regardless of what the FX controller asked for.
  • The FXBlurLow fragment shader didn't have the offset uniform. This is now passed in and applied to the resulting blur, preventing it from creating 45 degree artifacts (thanks Wayfinder)
  • The Tilemap.createFromObjects method wouldn't always copy custom properties to the target objects or Data Manager. Fix #6391 (thanks @samme @paxperscientiam)
  • The scale.min and scale.max width and height properties in Game Config were ignored by the Game constructor, which was expecting minWidth and minHeight. This now matches the documentation. Fix #6501 (thanks @NikitaShpanko @wpederzoli)
  • Due to a copy-paste bug, the Actions.GetLast function had the same code as the GetFirst function. It now does what you'd expect it to do. Fix #6513 (thanks @dmokel)
  • The TilemapLayer.PutTileAt method would use an incorrect local GID if the Tilemap Layer wasn't using all available tilesets. Fix #5931 (thanks @christianvoigt @wjaykim)
  • The TextureManager.addSpriteSheet method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @charlieschwabacher)
  • The HexagonalCullBounds function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The HexagonalGetTileCorners function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The HexagonalTileToWorldXY function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The BitmapText Game Object will now reset the WebGL Texture unit on flush, which fixes an issue of a flush happening part-way during the rendering a BitmapText (thanks @EmilSV)
  • When using interpolation for a Particle Emitter operation, such as: x: { values: [ 50, 500, 200, 800 ] } it would fail to set the final value unless you specified the interpolation property as well. It now defaults to linear if not given. Fix #6551 (thanks @orcomarcio)
  • The Matter Physics ignoreGravity boolean is now checked during the Matter Engine internal functions, allowing this property to now work again. Fix #6473 (thanks @peer2p)
  • Group.createFromConfig will now check to see if the config contains either internalCreateCallback or internalRemoveCallback and set them accordingly. This fixes an issue where the callbacks would never be set if specified in an array of single configuration objects. Fix #6519 (thanks @samme)
  • PhysicsGroup will now set the classType and null the config when an array of single configuration objects is given in the constructor. Fix #6519 (thanks @samme)
  • The PathFollower.pathUpdate method will now check if the tween property has a valid data component before running the update. This prevents a call to PathFollower.stopFollow from throwing a Cannot read properties of null (reading '0') error as it tried to do a single update post stop. Fix #6508 (thanks @francois-dibulo)
  • Added missing parameter to some function calls in Structs.ProcessQueue#add (thanks @Trissolo)
  • Tile was incorrectly using the Alpha Game Object component, instead of the AlphaSingle component, which meant although the methods implied you could set a different alpha per tile corner, it was never reflected in the rendering. It has now been updated to use just the single alpha value. Fix #6594 (thanks @jcoppage)
  • The TextureManager.addAtlasJSONArray method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addAtlasJSONHash method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addAtlasXML method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • The TextureManager.addUnityAtlas method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @1DAfT)
  • DynamicTexture.preDestroy was never called, leading to an accumulation of framebuffers in memory. This method has now been renamed to destroy and cleans all references correctly.
  • If you gave the width or height in the Game Config object as a string it would multiply the value given by the parent size, often leading to a huge game canvas, or causing WebGL errors as it tried to create a texture larger than the GPU could handle. This has now been strengthened. If you give a string with a % at the end, it works as before, i.e. "100%" or "50%" to set the scale based on the parent. If you don't include the %, or use another unit, such as "800px" it will now be treated as a fixed value, not a percentage.
  • The ParticleEmitterWebGLRenderer has been refactored so that the particle.frame is used as the source of the glTexture used in the batch and also if a new texture unit is required. This fixes issues where a Particle Emitter would fail to use the correct frame from a multi-atlas texture. Fix #6515 (thanks @Demeno)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @AlvaroEstradaDev @julescubtree @emadkhezri

- JavaScript
Published by photonstorm over 2 years ago

phaser - Phaser 3.61.0 Beta 1

New Features

  • Text.setRTL is a new method that allows you to set a Text Game Object as being rendered from right-to-left, instead of the default left to right (thanks @rexrainbow)
  • FX.Circle.backgroundAlpha is a new property that allows you to set the amount of the alpha of the background color in the Circle FX (thanks @rexrainbow)
  • Physics.Arcade.World.singleStep is a new method that will advance the Arcade Physics World simulation by exactly 1 step (thanks @monteiz)
  • Tilemaps.ObjectLayer.id is a new property that returns the ID of the Object Layer, if specified within Tiled, or zero otherwise. You can now access the unique layer ID of Tiled layers if the event a map doesn't have unique layer names (thanks @rui-han-crh)
  • Tilemaps.LayerData.id is a new property that returns the ID of the Data Layer, if specified within Tiled, or zero otherwise (thanks @rui-han-crh)
  • Text.setLetterSpacing is a new method and Text.lineSpacing is the related property that allows you to set the spacing between each character of a Text Game Object. The value can be either negative or positive, causing the characters to get closer or further apart. 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 (thanks @Ariorh1337)
  • ParticleEmitter.clearDeathZones is a new method that will clear all previously created Death Zones from a Particle Emitter (thanks @rexrainbow)
  • ParticleEmitter.clearEmitZones is a new method that will clear all previously created Emission Zones from a Particle Emitter (thanks @rexrainbow)

Updates

  • The WebAudioSoundManager will now bind the body to the removeEventListener method, if it exists, to prevent memory leaks (thanks @wjaykim)
  • The AnimationManager.globalTimeScale property is now applied to all Game Objects using the Animation component, allowing you to globally speed-up or slow down all animating objects (thanks @TJ09)
  • The Rope Game Object now calls initPostPipeline allowing you to use Post FX directly on it, such as glow, blur, etc. Fix #6550 (thanks @rexrainbow)
  • The Tween.stop method will now check to see if Tween.parent is set. If not, it won't try to set a pending removal state or dispatch an event, which should help guard against errors where Tween.stop is called by mistake on already destroyed tweens (thanks @orcomarcio)
  • The Tween.remove method will now check to see if Tween.parent exists before trying to remove it from the parent. This should help guard against errors where Tween.remove is called by mistake on already removed or destroyed tweens. Fix #6539 (thanks @orcomarcio)
  • Particle.alpha is now clamped to the range 0 to 1 within the update method, preventing it from going out of range. Fix #6551 (thanks @orcomarcio)
  • Math.Wrap has been reverted to the previous version. Fix #6479 (thanks @EmilSV)

Bug Fixes

  • Particle.scaleY would always be set to the scaleX value, even if given a different one within the config. It will now use its own value correctly.
  • Array.Matrix.RotateLeft was missing the total parameter, which controls how many times to rotate the matrix.
  • Array.Matrix.RotateRight was missing the total parameter, which controls how many times to rotate the matrix.
  • Array.Matrix.TranslateMatrix didn't work with any translation values above 1 due to missing parameters in RotateLeft and RotateRight
  • FX.Blur didn't set the quality parameter to its property, meaning it wasn't applied in the shader, causing it to always use a Low Blur quality (unless modified post-creation).
  • The BlurFXPipeline didn't bind the quality of shader specified in the controller, meaning it always used the Low Blur shader, regardless of what the FX controller asked for.
  • The FXBlurLow fragment shader didn't have the offset uniform. This is now passed in and applued to the resulting blur, preventing it from creating 45 degree artifacts (thanks Wayfinder)
  • The Tilemap.createFromObjects method wouldn't always copy custom properties to the target objects or Data Manager. Fix #6391 (thanks @samme @paxperscientiam)
  • The scale.min and scale.max width and height properties in Game Config were ignored by the Game constructor, which was expecting minWidth and minHeight. This now matches the documnentation. Fix #6501 (thanks @NikitaShpanko @wpederzoli)
  • Due to a copy-paste bug, the Actions.GetLast function had the same code as the GetFirst function. It now does what you'd expect it to do. Fix #6513 (thanks @dmokel)
  • The TilemapLayer.PutTileAt method would use an incorrect local GID if the Tilemap Layer wasn't using all available tilesets. Fix #5931 (thanks @christianvoigt @wjaykim)
  • The TextureManager.addSpriteSheet method would fail if a Texture instance was given as the second parameter, throwing a Cannot read property 'key' of null (thanks @charlieschwabacher)
  • The HexagonalCullBounds function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The HexagonalGetTileCorners function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The HexagonalTileToWorldXY function incorrectly referenced this within it, instead of layer (thanks @DaliborTrampota)
  • The BitmapText Game Object will now reset the WebGL Texture unit on flush, which fixes an issue of a flush happened part-way during the rendering a BitmapText (thanks @EmilSV)
  • When using interpolation for a Particle Emitter operation, such as: x: { values: [ 50, 500, 200, 800 ] } it would fail to set the final value unless you specified the interpolation property as well. It now defaults to linear if not given. Fix #6551 (thanks @orcomarcio)
  • The Matter Physics ignoreGravity boolean is now checked during the Matter Engine internal functions, allowing this property to now work again. Fix #6473 (thanks @peer2p)
  • Group.createFromConfig will now check to see if the config contains either internalCreateCallback or internalRemoveCallback and set them accordingly. This fixes an issue where the callbacks would never be set if specified in an array of single configuration objects. Fix #6519 (thanks @samme)
  • PhysicsGroup will now set the classType and null the config when an array of single configuration objects is given in the constructor. Fix #6519 (thanks @samme)
  • The PathFollower.pathUpdate method will now check if the tween property has a valid data component before running the update. This prevents a call to PathFollower.stopFollow from throwing a Cannot read properties of null (reading '0') error as it tried to do a single update post stop. Fix #6508 (thanks @francois-dibulo)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme

- JavaScript
Published by photonstorm almost 3 years ago

phaser - Phaser v3.60.0

Due to the size and importance of the v3.60 release, we have split the Change Log up into multiple sections.

This makes it easier for you to browse and find the information you need.

New Features

These are the headliner features in this release:

System and Plugins

Pick any of the following sections to see the breaking changes, new features, updates, and bug fixes for that area of the API.

Game Object Updates

Finally, here are the updates related to Game Objects:

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

| 💖 | 💖 | 💖 | 💖 | | ----- | ----- | ----- | ----- | | @0day-oni | @201flaviosilva | @AlbertMontagutCasero | @Arcanorum | | @arosemena | @austinlyon | @chrisl8 | @christian-post | | @danfoster | @darrylpizarro | @DeweyHur | @drunkcat | | @ef4 | @eltociear | @EsteFilipe | @etherealmachine | | @EmilSV | @Fake | @florestankorp | @hacheraw | | @hanzooo | @jerricko | @joegaffey | @jonasrundberg | | @kainage | @kootoopas | @lolimay | @MaffDev | | @michalfialadev | @monteiz | @necrokot | @Nero0 | | @OdinvonDoom | @orjandh | @pavle-goloskokovic | @PhaserEditor2D | | @Pythux | @quocsinh | @rgk | @rollinsafary-inomma | | @rstanuwijaya | 👑 @samme 👑 | @Smirnov48 | @steveja42 | | @sylvainpolletvillard | @twoco | @ubershmekel | @ultimoistante | | @VanaMartin | @vforsh | @Vidminas | @x-wk | | @xmahle | @xuxucode | @YeloPartyHat | @ZekeLu | | FromChris | Golen | OmniOwl | and you ... |

📖 Read the Phaser 3 API Docs 💻 Browse 2000+ Code Examples 🤝 Join the awesome Phaser Discord

- JavaScript
Published by photonstorm about 3 years ago

phaser - Phaser v3.60 Beta 23

Version 3.60.0 - Miku - in development

New Features - Timeline Class

Phaser 3.60 has a new Timeline Class which allows for fine-grained control of sequenced events. Previously in 3.55 the Timeline was part of the Tween system and it never quite worked as intended. In 3.60 it has been removed from Tweens entirely, replaced with the much more solid and reliable Tween Chains and Timeline has now becomes its own first-class citizen within Phaser. It allows you to sequence any event you like, not just tweens.

A Timeline is a way to schedule events to happen at specific times in the future. You can think of it as an event sequencer for your game, allowing you to schedule the running of callbacks, events and other actions at specific times in the future.

A Timeline is a Scene level system, meaning you can have as many Timelines as you like, each belonging to a different Scene. You can also have multiple Timelines running at the same time.

If the Scene is paused, the Timeline will also pause. If the Scene is destroyed, the Timeline will be automatically destroyed. However, you can control the Timeline directly, pausing, resuming and stopping it at any time.

Create an instance of a Timeline via the Game Object Factory:

js const timeline = this.add.timeline();

The Timeline always starts paused. You must call play on it to start it running.

You can also pass in a configuration object on creation, or an array of them:

```js const timeline = this.add.timeline({ at: 1000, run: () => { this.add.sprite(400, 300, 'logo'); } });

timeline.play(); ```

In this example we sequence a few different events:

```js const timeline = this.add.timeline([ { at: 1000, run: () => { this.logo = this.add.sprite(400, 300, 'logo'); }, sound: 'TitleMusic' }, { at: 2500, tween: { targets: this.logo, y: 600, yoyo: true }, sound: 'Explode' }, { at: 8000, event: 'HURRY_PLAYER', target: this.background, set: { tint: 0xff0000 } } ]);

timeline.play(); ```

There are lots of options available to you via the configuration object. See the TimelineEventConfig typedef for more details.

New Features - ESM Support

Phaser 3.60 uses the new release of Webpack 5 in order to handle the builds. The configurations have been updated to follow the new format this upgrade introduced. As a bonus, Webpack 5 also bought a new experimental feature called 'output modules', which will take a CommonJS code-base, like Phaser uses and wrap the output in modern ES Module declarations.

We are now using this as part of our build. You will find in the dist folder a new phaser.esm.js file, which is also linked in from our package.json module property. Using this build you can access any of the Phaser modules directly via named imports, meaning you can code like this:

```js import { AUTO, Scene, Game } from './phaser.esm.js';

class Test extends Scene { constructor () { super(); }

create ()
{
    this.add.text(10, 10, 'Welcome to Phaser ESM');
}

}

const config = { type: AUTO, width: 800, height: 600, parent: 'phaser-example', scene: [ Test ] };

const game = new Game(config); ```

Note that we're importing from the local esm bundle. By using this approach you don't need to even use a bundler for quick local prototyping or testing, you can simply import and code directly.

The dist folder still also contains phaser.js which, as before, uses a UMD export.

Because the Webpack feature is experimental we won't make the ESM version the default just yet, but if you're curious and want to explore, please go ahead!

New Features - Built-in Special FX

We have decided to bundle a selection of highly flexible special effect shaders in to Phaser 3.60 and provide access to them via an easy to use set of API calls. The FX included are:

  • Barrel - A nice pinch / bulge distortion effect.
  • Bloom - Add bloom to any Game Object, with custom offset, blur strength, steps and color.
  • Blur - 3 different levels of gaussian blur (low, medium and high) and custom distance and color.
  • Bokeh / TiltShift - A bokeh and tiltshift effect, with intensity, contrast and distance settings.
  • Circle - Add a circular ring around any Game Object, useful for masking / avatar frames, with custom color, width and background color.
  • ColorMatrix - Add a ColorMatrix to any Game Object with access to all of its methods, such as sepia, greyscale, lsd and lots more.
  • Displacement - Use a displacement texture, such as a noise texture, to drastically (or subtly!) alter the appearance of a Game Object.
  • Glow - Add a smooth inner or outer glow, with custom distance, strength and color.
  • Gradient - Draw a gradient between two colors across any Game Object, with optional 'chunky' mode for classic retro style games.
  • Pixelate - Make any Game Object appear pixelated, to a varying degree.
  • Shadow - Add a drop shadow behind a Game Object, with custom depth and color.
  • Shine - Run a 'shine' effect across a Game Object, either additively or as part of a reveal.
  • Vignette - Apply a vignette around a Game Object, with custom offset position, radius and color.
  • Wipe - Set a Game Object to 'wipe' or 'reveal' with custom line width, direction and axis of the effect.

What's more, the FX can be stacked up. You could add, for example, a Barrel followed by a Blur and then topped-off with a Circle effect. Just by adjusting the ordering you can achieve some incredible and unique effects, very quickly.

We've worked hard to make the API as easy to use as possible, too. No more messing with pipelines or importing plugins. You can simply do:

```js const player = this.add.sprite(x, y, texture);

player.preFX.addGlow(0xff0000, 32); ```

This will add a 32 pixel red glow around the player Sprite.

Each effect returns a new FX Controller instance, allowing you to easily adjust the special effects in real-time via your own code, tweens and similar:

```js const fx = container.postFX.addWipe();

this.tweens.add({ targets: fx, progress: 1 }); ```

This will add a Wipe Effect to a Container instance and then tween its progress value from 0 to 1, causing the wipe to play out.

All texture-based Game Objects have access to Pre FX (so that includes Images, Sprites, TileSprites, Text, RenderTexture and Video). However, all Game Objects have access to Post FX, as do cameras. The difference is just when the effect is applied. For a 'pre' effect, it is applied before the Game Object is drawn. For a 'post' effect, it's applied after it has been drawn. All of the same effects are available to both.

js this.cameras.main.postFX.addTiltShift();

For example, this will apply a Tilt Shift effect to everything being rendered by the Camera. Which is a much faster way of doing it than applying the same effect to every child in a Scene. You can also apply them to Containers, allowing more fine-grained control over the display.

The full list of new methods are as follows:

Available only to texture-based Game Objects:

  • GameObject.preFX an instance of the FX Controller, which allows you to add and remove Pre FX from the Game Object. It features methods such as add, remove and clear. Plus the following:

  • GameObject.preFX.addGlow adds a Glow Pre FX effect to the Game Object.

  • GameObject.preFX.addShadow adds a Shadow Pre FX effect to the Game Object.

  • GameObject.preFX.addPixelate adds a Pixelate Pre FX effect to the Game Object.

  • GameObject.preFX.addVignette adds a Vignette Pre FX effect to the Game Object.

  • GameObject.preFX.addShine adds a Shine Pre FX effect to the Game Object.

  • GameObject.preFX.addBlur adds a Blur Pre FX effect to the Game Object.

  • GameObject.preFX.addGradient adds a Gradient Pre FX effect to the Game Object.

  • GameObject.preFX.addBloom adds a Bloom Pre FX effect to the Game Object.

  • GameObject.preFX.addColorMatrix adds a ColorMatrix Pre FX effect to the Game Object.

  • GameObject.preFX.addCircle adds a Circle Pre FX effect to the Game Object.

  • GameObject.preFX.addBarrel adds a Barrel Pre FX effect to the Game Object.

  • GameObject.preFX.addDisplacement adds a Displacement Pre FX effect to the Game Object.

  • GameObject.preFX.addWipe adds a Wipe Pre FX effect to the Game Object.

  • GameObject.preFX.addReveal adds a Reveal Pre FX effect to the Game Object.

  • GameObject.preFX.addBokeh adds a Bokeh Pre FX effect to the Game Object.

  • GameObject.preFX.addTiltShift adds a TiltShift Pre FX effect to the Game Object.

Available to all Game Objects:

  • GameObject.clearFX removes both Pre and Post FX from the Game Object.
  • GameObject.postFX an instance of the FX Controller, which allows you to add and remove Post FX from the Game Object. It features methods such as add, remove and clear. Plus the following:

  • GameObject.postFX.addGlow adds a Glow Post FX effect to the Game Object.

  • GameObject.postFX.addShadow adds a Shadow Post FX effect to the Game Object.

  • GameObject.postFX.addPixelate adds a Pixelate Post FX effect to the Game Object.

  • GameObject.postFX.addVignette adds a Vignette Post FX effect to the Game Object.

  • GameObject.postFX.addShine adds a Shine Post FX effect to the Game Object.

  • GameObject.postFX.addBlur adds a Blur Post FX effect to the Game Object.

  • GameObject.postFX.addGradient adds a Gradient Post FX effect to the Game Object.

  • GameObject.postFX.addBloom adds a Bloom Post FX effect to the Game Object.

  • GameObject.postFX.addColorMatrix adds a ColorMatrix Post FX effect to the Game Object.

  • GameObject.postFX.addCircle adds a Circle Post FX effect to the Game Object.

  • GameObject.postFX.addBarrel adds a Barrel Post FX effect to the Game Object.

  • GameObject.postFX.addDisplacement adds a Displacement Post FX effect to the Game Object.

  • GameObject.postFX.addWipe adds a Wipe Post FX effect to the Game Object.

  • GameObject.postFX.addReveal adds a Reveal Post FX effect to the Game Object.

  • GameObject.postFX.addBokeh adds a Bokeh Post FX effect to the Game Object.

  • GameObject.postFX.addTiltShift adds a TiltShift Post FX effect to the Game Object.

New Features - Spatial Sound

Thanks to a contribution from @alxwest the Web Audio Sound system now supports spatial sound. The Web Audio Sound Manager now has the ability to set the listener position and each sound can be positioned in 3D space:

```js this.music = this.sound.add('theme');

this.sound.setListenerPosition(400, 300);

this.music.play({ loop: true, source: { x: 400, y: 300, refDistance: 50, follow: this.playerSprite } }); ```

This allows you to create a 3D sound environment in your game. The following new methods and properties have been added to the Web Audio Sound Manager and Web Audio Sound classes:

  • SpatialSoundConfig is a new configuration object that contains the properties required to create and set the values of a spatial sound:
  • SpatialSoundConfig.x sets the horizontal position of the audio in a right-hand Cartesian coordinate system.
  • SpatialSoundConfig.y sets the vertical position of the audio in a right-hand Cartesian coordinate system.
  • SpatialSoundConfig.z sets the longitudinal (back and forth) position of the audio in a right-hand Cartesian coordinate system.
  • SpatialSoundConfig.panningModel is an enumerated value determining which spatialization algorithm to use to position the audio in 3D space. Can be either equalpower or HRTF. The default value is equalpower.
  • SpatialSoundConfig.distanceModel sets which algorithm to use to reduce the volume of the audio source as it moves away from the listener. Possible values are "linear", "inverse" and "exponential". The default value is "inverse".
  • SpatialSoundConfig.orientationX sets the horizontal position of the audio source's vector in a right-hand Cartesian coordinate system.
  • SpatialSoundConfig.orientationY sets the vertical position of the audio source's vector in a right-hand Cartesian coordinate system.
  • SpatialSoundConfig.orientationZ sets the longitudinal (back and forth) position of the audio source's vector in a right-hand Cartesian coordinate system.
  • SpatialSoundConfig.refDistance is a double value representing the reference distance for reducing volume as the audio source moves further from the listener. For distances greater than this the volume will be reduced based on rolloffFactor and distanceModel.
  • SpatialSoundConfig.maxDistance is the maximum distance between the audio source and the listener, after which the volume is not reduced any further.
  • SpatialSoundConfig.rolloffFactor is a double value describing how quickly the volume is reduced as the source moves away from the listener. This value is used by all distance models.
  • SpatialSoundConfig.coneInnerAngle sets the angle, in degrees, of a cone inside of which there will be no volume reduction.
  • SpatialSoundConfig.coneOuterAngle sets the angle, in degrees, of a cone outside of which the volume will be reduced by a constant value, defined by the coneOuterGain property.
  • SpatialSoundConfig.coneOuterGain sets the amount of volume reduction outside the cone defined by the coneOuterAngle attribute. Its default value is 0, meaning that no sound can be heard. A value between 0 and 1.
  • SpatialSoundConfig.follow sets this Sound object to automatically track the x/y position of this object. Can be a Phaser Game Object, Vec2 or anything that exposes public x/y properties.
  • WebAudioSoundManager.setListenerPosition is a new method that allows you to set the position of the Spatial Audio listener.
  • BaseSoundManager.listenerPosition is a new Vector2 that stores the position of the Spatial Audio listener.
  • WebAudioSound.spatialNode is a new property that holds the PanNode that is used to position the sound in 3D space.
  • WebAudioSound.spatialSource is a new property that holds a Vector2 that stores the position of the sound in 3D space.
  • WebAudioSound.x is a new property that sets the x position of the sound in 3D space. This only works if the sound was created with a SpatialSoundConfig object.
  • WebAudioSound.y is a new property that sets the y position of the sound in 3D space. This only works if the sound was created with a SpatialSoundConfig object.

New Features - Spine 4 Support

Thanks to a contribution from @justintien we now have a Spine 4 Plugin available.

You can find it in the plugins/spine4.1 folder in the main repository. There are also a bunch of new npm scripts to help build this plugin:

npm run plugin.spine4.1.full.dist - To build new dist files for both canvas and WebGL. npm run plugin.spine4.1.dist - To build new dist files. npm run plugin.spine4.1.watch - To enter watch mode when doing dev work on the plugin. npm run plugin.spine4.1.runtimes - To build new versions of the Spine 4 runtimes.

The core plugin API remains largely the same. You can find lots of updated examples in the Phaser 3 Examples repo in the 3.60/spine4.1 folder.

We will maintain both the Spine 3 and 4 plugins for the forseeable future.

Additional Spine 3 Bug Fixes

  • Using drawDebug on a Spine Game Object to view its skeleton would cause the next object in the display list to be skipped for rendering, if it wasn't a Spine Game Object too. This is because the Spine 3 skeleton debug draw ends the spine batch but the Scene Renderer wasn't rebound. Fix #6380 (thanks @spayton)
  • The Spine Plugin add and make functions didn't clear and rebind the WebGL pipeline. This could cause two different visual issues: The first is that a Phaser Game Object (such as a Sprite) could be seen to change its texture to display the Spine atlas texture instead for a single frame, and then on the next pass revert back to normal again. The second issue is that if the Spine skeleton wasn't added to the display list, but just created (via addToScene: false) then the Sprite would take on the texture frame entirely from that point on. Fix #6362 (thanks @frissonlabs)
  • Previously, it wasn't possible for multiple Spine Atlases to use PNGs with the exact same filename, even if they were in different folders. The SpineFile loader has now been updated so that the always-unique Spine key is pre-pended to the filename, for example if the key was bonus and the PNG in the atlas was coin.png then the final key (as stored in the Texture Manager) is now bonus:coin.png. The SpinePlugin.getAtlasCanvas and getAtlasWebGL methods have been updated to reflect this change. Fix #6022 (thanks @orjandh)
  • If a SpineContainer had a mask applied to it and the next immediate item on the display list was another Spine object (outside of the Container) then it would fail to rebind the WebGL pipeline, causing the mask to break. It will now rebind the renderer at the end of the SpineContainer batch, no matter what, if it has a mask. Fix #5627 (thanks @FloodGames)

New Features - Plane Game Object

Phaser v3.60 contains a new native Plane Game Object. The Plane Game Object is a helper class that takes the Mesh Game Object and extends it, allowing for fast and easy creation of Planes. A Plane is a one-sided grid of cells, where you specify the number of cells in each dimension. The Plane can have a texture that is either repeated (tiled) across each cell, or applied to the full Plane.

The Plane can then be manipulated in 3D space, with rotation across all 3 axis.

This allows you to create effects not possible with regular Sprites, such as perspective distortion. You can also adjust the vertices on a per-vertex basis. Plane data becomes part of the WebGL batch, just like standard Sprites, so doesn't introduce any additional shader overhead. Because the Plane just generates vertices into the WebGL batch, like any other Sprite, you can use all of the common Game Object components on a Plane too, such as a custom pipeline, mask, blend mode or texture.

You can use the uvScroll and uvScale methods to adjust the placement and scaling of the texture if this Plane is using a single texture, and not a frame from a texture atlas or sprite sheet.

The Plane Game Object also has the Animation component, allowing you to play animations across the Plane just as you would with a Sprite.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Nine Slice Game Object

Phaser v3.60 contains a new native Nine Slice Game Object. A Nine Slice Game Object allows you to display a texture-based object that can be stretched both horizontally and vertically, but that retains fixed-sized corners. The dimensions of the corners are set via the parameters to the class. When you resize a Nine Slice Game Object only the middle sections of the texture stretch. This is extremely useful for UI and button-like elements, where you need them to expand to accommodate the content without distorting the texture.

The texture you provide for this Game Object should be based on the following layout structure:

A B +---+----------------------+---+ C | 1 | 2 | 3 | +---+----------------------+---+ | | | | | 4 | 5 | 6 | | | | | +---+----------------------+---+ D | 7 | 8 | 9 | +---+----------------------+---+

When changing this objects width and / or height:

areas 1, 3, 7 and 9 (the corners) will remain unscaled
areas 2 and 8 will be stretched horizontally only
areas 4 and 6 will be stretched vertically only
area 5 will be stretched both horizontally and vertically

You can also create a 3 slice Game Object:

This works in a similar way, except you can only stretch it horizontally. Therefore, it requires less configuration:

A B +---+----------------------+---+ | | | | C | 1 | 2 | 3 | | | | | +---+----------------------+---+

When changing this objects width (you cannot change its height)

areas 1 and 3 will remain unscaled
area 2 will be stretched horizontally

The above configuration concept is adapted from the Pixi NineSlicePlane.

To specify a 3 slice object instead of a 9 slice you should only provide the leftWidth and rightWidth parameters. To create a 9 slice you must supply all parameters.

The minimum width this Game Object can be is the total of leftWidth + rightWidth. 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 scale it.

In terms of performance, using a 3 slice Game Object is the equivalent of having 3 Sprites in a row. Using a 9 slice Game Object is the equivalent of having 9 Sprites in a row. The vertices of this object are all batched together and can co-exist with other Sprites and graphics on the display list, without incurring any additional overhead.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Pre FX Pipeline

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isPreFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Pre FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all PreFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Pre FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.
  • The WebGLPipeline.setTime method has a new optional parameter shader, which allows you to control the shader on which the time value is set.
  • If you add #define SHADER_NAME to the start of your shader then it will be picked up as the WebGLShader name during the setShadersFromConfig process within WebGLPipeline.
  • Calling setPostPipeline on a Game Object will now pass the pipelineData configuration object (if provided) to the pipeline instance being created.
  • PipelineManager.getPostPipeline now has an optional 3rd parameter, a config object that is passed to the pipeline instance in its constructor, which can be used by the pipeline during its set-up.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Updated Particle System

The Particle system has been mostly rewritten to give it a much needed overhaul. This makes the API cleaner, the Game Objects a lot more memory efficient and also introduces several great new features. In order to do this, we had to make some breaking changes. The largest being the way in which particles are now created.

Previously when you used the this.add.particles command it would create a ParticleEmitterManager instance. You would then use this to create an Emitter, which would actually emit the particles. While this worked and did allow a Manager to control multiple emitters we found that in discussion developers seldom used this feature and it was common for a Manager to own just one single Emitter.

In order to streamline memory and the display list we have removed the ParticleEmitterManager entirely. When you call this.add.particles you're now creating a ParticleEmitter instance, which is being added directly to the display list and can be manipulated just like any other Game Object, i.e. scaled, rotated, positioned, added to a Container, etc. It now extends the GameObject base class, meaning it's also an event emitter, which allowed us to create some handy new events for particles.

So, to create an emitter, you now give it an xy coordinate, a texture and an emitter configuration object (you can also set this later, but most commonly you'd do it on creation). I.e.:

js const emitter = this.add.particles(100, 300, 'flares', { frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

This will create a 'red flare' emitter at 100 x 300.

Prior to 3.60 it would have looked like:

```js const manager = this.add.particles('flares');

const emitter = manager.createEmitter({ x: 100, y: 300, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 }); ```

The change is quite subtle but makes a big difference internally.

The biggest real change is with the particle x/y coordinates. It's important to understand that if you define x/y coordinates within the emitter configuration, they will be relative to those given in the add.particles call:

js const emitter = this.add.particles(100, 300, 'flares', { x: 100, y: 100, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

In the above example the particles will emit from 200 x 400 in world space, because the emitter is at 100 x 300 and the particles emit from an offset of 100 x 100.

By making this change it now means you're able to do things like tween the x/y coordinates of the emitter (something you couldn't do before), or add a single emitter to a Container.

Other new features include:

Animated Particles

The Particle class now has an instance of the Animation State component within it. This allows a particle to play an animation when it is emitted, simply by defining it in the emitter config.

For example, this will make each particle play the 'Prism' animation on emission:

js const emitter = this.add.particles(400, 300, 'gems', { anim: 'prism' ... });

You can also allow it to select a random animation by providing an array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: [ 'prism', 'square', 'ruby', 'square' ] ... });

You've also the ability to cycle through the animations in order, so each new particle gets the next animation in the array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'square', 'ruby', 'square' ], cycle: true } ... });

Or even set a quantity. For example, this will emit 10 'prism' particles, then 10 'ruby' particles and then repeat:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'ruby' ], cycle: true, quantity: 10 } ... });

The Animations must have already been created in the Global Animation Manager and must use the same texture as the one bound to the Particle Emitter. Aside from this, you can still control them in the same way as any other particle - scaling, tinting, rotation, alpha, lifespan, etc.

Fast Forward Particle Time

  • You can now 'fast forward' a Particle Emitter. This can be done via either the emitter config, using the new advance property, or by calling the new ParticleEmitter.fastForward method. If, for example, you have an emitter that takes a few seconds to 'warm up' and get all the particles into position, this allows you to 'fast forward' the emitter to a given point in time. The value is given in ms. All standard emitter events and callbacks are still handled, but no rendering takes place during the fast-forward until it has completed.
  • The ParticleEmitter.start method has a new optional parameter advance that allows you to fast-forward the given amount of ms before the emitter starts flowing.

Particle Interpolation

  • It's now possible to create a new Interpolation EmitterOp. You do this by providing an array of values to interpolate between, along with the function name:

js const emitter = this.add.particles(0, 0, 'texture', { x: { values: [ 50, 500, 200, 800 ], interpolation: 'catmull' } ... });

This will interpolate the x property of each particle through the data set given, using a catmull rom interpolation function. You can also use linear or bezier functions. Interpolation can be combined with an ease type, which controls the progression through the time value. The related EmitterOpInterpolationConfig types have also been added.

Particle Emitter Duration

  • The Particle Emitter config has a new optional parameter duration:

js const emitter = this.add.particles(0, 0, 'texture', { speed: 24, lifespan: 1500, duration: 500 });

This parameter is used for 'flow' emitters only and controls how many milliseconds the emitter will run for before automatically turning itself off.

  • ParticleEmitter.duration is a new property that contains the duration that the Emitter will emit particles for in flow mode.
  • The ParticleEmitter.start method has a new optional parameter duration, which allows you to set the emitter duration when you call this method. If you do this, it will override any value set in the emitter configuration.
  • The ParticleEmitter.stop method has a new optional parameter kill. If set it will kill all alive particles immediately, rather than leaving them to die after their lifespan expires.

Stop After a set number of Particles

  • The Particle Emitter config has a new optional stopAfter property. This, combined with the frequency property allows you to control exactly how many particles are emitted before the emitter then stops:

js const emitter = this.add.particles(0, 0, 'texture', { x: { start: 400, end: 0 }, y: { start: 300, end: 0 }, lifespan: 3000, frequency: 250, stopAfter: 6, quantity: 1 });

In the above code the emitter will launch 1 particle (set by the quantity property) every 250 ms (set by the frequency property) and move it to xy 0x0. Once it has fired 6 particles (the stopAfter property) the emitter will stop and emit the COMPLETE event.

  • The stopAfter counter is reset each time you call the start or flow methods.

Particle Hold

  • You can configure a Particle to be frozen or 'held in place' after it has finished its lifespan for a set number of ms via the new hold configuration option:

js const emitter = this.add.particles(0, 0, 'texture', { lifespan: 2000, scale: { start: 0, end: 1 }, hold: 1000 ... });

The above will scale a Particle in from 0 to 1 over the course of its lifespan (2 seconds). It will then hold it on-screen for another second (1000 ms) before the Emitter recycles it and removes it from display.

Particle Emitter Events

  • The Particle Emitter will now fire 5 new events. Listen for the events as follows:

```js const emitter = this.add.particles(0, 0, 'flares');

emitter.on('start', (emitter) => { // emission started });

emitter.on('explode', (emitter, particle) => { // emitter 'explode' called });

emitter.on('deathzone', (emitter, particle, deathzone) => { // emitter 'death zone' called });

emitter.on('stop', (emitter) => { // emission has stopped });

emitter.on('complete', (emitter) => { // all particles fully dead }); ```

  • The Particles.Events.START event is fired whenever the Emitter begins emission of particles in flow mode. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.EXPLODE event is fired whenever the Emitter explodes a bunch of particles via the explode method. A reference to the ParticleEmitter and a reference to the most recently fired Particle instance are the two parameters.
  • The Particles.Events.DEATH_ZONE event is fired whenever a Particle is killed by a Death Zone. A reference to the ParticleEmitter, the killed Particle and the DeathZone that caused it are the 3 parameters.
  • The Particles.Events.STOP event is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call the stop method, or when an Emitter hits its duration or stopAfter limit. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.COMPLETE event is fired when the final alive particle expires.

Multiple Emit Zones

  • In v3.60 a Particle Emitter can now have multiple emission zones. Previously, an Emitter could have only a single emission zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addEmitZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addEmitZone({ type: 'edge', source: circle, quantity: 64 }); ```

  • When an Emitter has more than one emission zone, the Particles will cycle through the zones in sequence. For example, an Emitter with 3 zones would emit its first particle from zone 1, the second from zone 2, the third from zone 3, the fourth from zone 1, etc.
  • You can control how many particles are emitted from a single zone via the new total property. EdgeZone.total and RandomZone.total are new properties that control the total number of particles the zone will emit, before passing control over to the next zone in the list, if any. The default is -1.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeEmitZone is a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getEmitZone is a new method that Particles call when they are 'fired' in order to set their starting position, if any.
  • The property ParticleEmitter.emitZone has been removed. It has been replaced with the new ParticleEmitter.emitZones array-based property.

Multiple Death Zones

  • In v3.60 a Particle Emitter can now have multiple death zones. Previously, an Emitter could have only a single death zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addDeathZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addDeathZone({ type: 'onEnter', source: circle }); ```

  • When an Emitter has more than one Death Zone, the Particles will check themselves against all of the Death Zones, to see if any of them kills them.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeDeathZone is a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getDeathZone is a new method that Particles call when they are updated in order to check if they intersect with any of the Death Zones.
  • The property ParticleEmitter.deathZone has been removed. It has been replaced with the new ParticleEmitter.deathZones array-based property.

Particle Colors

  • You can now specify a new color property in the Emitter configuration. This takes the form of an array of hex color values that the particles will linearly interpolate between during theif lifetime. This allows you to now change the color of a particle from birth to death, which gives you far more control over your emitter visuals than ever before. You'd use it as follows:

js const flame = this.add.particles(150, 550, 'flares', { frame: 'white', color: [ 0xfacc22, 0xf89800, 0xf83600, 0x9f0404 ], colorEase: 'quad.out', lifespan: 2400, angle: { min: -100, max: -80 }, scale: { start: 0.70, end: 0, ease: 'sine.out' }, speed: 100, advance: 2000, blendMode: 'ADD' });

Here you can see the array of 4 colors it will interpolate through.

  • The new colorEase configuration property allows you to define the ease used to calculate the route through the interpolation. This can be set to any valid ease string, such as sine.out or quad.in, etc. If left undefined it will use linear as default.
  • EmitterColorOp is a brand new Emitter Op class that specifically controls the handling of color values, it extends EmitterOp and uses the same methods but configured for faster color interpolation.
  • If you define color in your config it will override any Emitter tint values you may have set. In short, use color if you wish to adjust the color of the particles during their lifespan and use tint if you wish to modify either the entire emitter at once, or the color of the particles on birth only.
  • ParticleEmitter.particleColor is a new property that allows you to get and set the particle color op value.
  • ParticleEmitter.colorEase is a new property that allows you to get and set the ease function used by the color op.

Particle Sort Order

  • You now have much more control over the sorting order of particles in an Emitter. You can set the new ParticleEmitter.sortProperty and sortOrderAsc properties to set how (and if) particles should be sorted prior to rendering. For example, setting sortProperty to y would mean that the particles will be sorted based on their y value prior to rendering. The sort order controls the order in which the particles are rendered. For example:

```js const emitter = this.add.particles(100, 300, 'blocks', { frame: 'redmonster', lifespan: 5000, angle: { min: -30, max: 30 }, speed: 150, frequency: 200 });

emitter.setSortProperty('y', true); ```

  • The new ParticleEmitter.setSortProperty method allows you to modify the sort property and order at run-time.
  • The new ParticleEmitter.setSortCallback method allows you to set a callback that will be invoked in order to sort the particles, rather than using the built-in one. This gives you complete freedom over the logic applied to particle render sorting.

Particle Bounds, Renderer Culling and Overlap

  • Particles now have the ability to calculate their bounding box, based on their position, scale, rotation, texture frame and the transform of their parent. You can call the new Particle.getBounds method to return the bounds, which also gets stored in the new Particle.bounds Rectangle property.
  • ParticleEmitter.getBounds is a new method that will return the bounds of the Emitter based on all currently active particles. Optional parameters allow you to pad out the bounds and/or advance time in the particle flow, to allow for a more accurate overall bounds generation.
  • ParticleEmitter.viewBounds is a new property that is a Geom Rectangle. Set this Rectangle to define the overall area the emitter will render to. If this area doesn't intersect with the Camera then the emitter will be culled from rendering. This allows you to populate large Scenes with active emitters that don't consume rendering resources even though they are offscreen. Use the new getBounds method to help define the viewBounds area.
  • ParticleEmitter.overlap is a new method that will run a rectangle intersection test against the given target and all alive particles, returning those that overlap in an array. The target can be a Rectangle Geometry object or an Arcade Physics Body.
  • Particle.kill is a new method that will set the life of the particle to zero, forcing it to be immediately killed on the next Particle Emitter update.
  • ParticleEmitter.getWorldTransformMatrix is a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.
  • ParticleEmitter.worldMatrix is a new property that holds a TransformMatrix used for bounds calculations.

Particle Emitter Bounds

  • Prior to v3.60 a Particle Emitter had a bounds property. This was a Rectangle and if a Particle hit any of its edges it would rebound off it based on the Particles bounce value. In v3.60 this action has been moved to a Particle Processor. You can still configure the bounds via the Emitter config using the bounds property, as before. And you can configure which faces collide via the collideLeft etc properties. However, the following internal changes have taken place:
  • ParticleBounds is a new Particle Processor class that handles updating the particles.
  • The ParticleEmitter.setBounds method has been replaced with ParticleEmitter.addParticleBounds which now returns a new ParticleBounds Particle Processor instance.
  • The ParticleEmitter.bounds property has been removed. Please see the addParticleBounds method if you wish to retain this object.
  • The ParticleEmitter.collideLeft property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideRight property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideTop property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideBottom property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The Particle.checkBounds method has been removed as it's now handled by the Particle Processors.

Particle Processors

  • ParticleProcessor is a new base class that you can use to create your own Particle Processors, which are special processors capable of manipulating the path of Particles based on your own logic or math. It provides the structure required to handle the processing of particles and should be used as a base for your own classes.
  • GravityWell now extends the new ParticleProcessor class.
  • ParticleEmitter.addParticleProcessor is a new method that allows you to add a Particle Processor instance to the Emitter. The old createGravityWell method now uses this.
  • ParticleEmitter.removeParticleProcessor is a new method that will remove a Particle Processor from an Emitter.
  • ParticleEmitter.processors is a new List property that contains all of the Particle Processors belonging to the Emitter.
  • The ParticleEmitter.wells property has been removed. You should now use the new processors property instead, they are functionally identical.
  • ParticleProcessor.update is the method that handles all of the particle manipulation. It now has a new 4th parameter t that is the normalized lifespan of the Particle being processed.

Particle System EmitterOp Breaking Changes and Updates:

All of the following properties have been replaced on the ParticleEmitter class. Previously they were EmitterOp instances. They are now public getter / setters, so calling, for example, emitter.particleX will now return a numeric value - whereas before it would return the EmitterOp instance. This gives developers a lot more freedom when using Particle Emitters. Before v3.60 it was impossible to do this, for example:

js this.tweens.add({ targets: emitter, particleX: 400 });

I.e. you couldn't tween an emitters particle spawn position by directly accessing its x and y properties. However, now that all EmitterOps are getters, you're free to do this, allowing you to be much more creative and giving a nice quality-of-life improvement.

If, however, your code used to access EmitterOps, you'll need to change it as follows:

```js // Phaser 3.55 emitter.x.onChange(value) // Phaser 3.60 emitter.particleX = value

// Phaser 3.55 let x = emitter.x.propertyValue // Phaser 3.60 let x = emitter.particleX

// Phaser 3.55 emitter.x.onEmit() emitter.x.onUpdate() // Phaser 3.60 emitter.ops.x.onEmit() emitter.ops.x.onUpdate() ```

All of following EmitterOp functions can now be found in the new ParticleEmitter.ops property and have been replaced with getters:

  • accelerationX
  • accelerationY
  • alpha
  • angle
  • bounce
  • color
  • delay
  • lifespan
  • maxVelocityX
  • maxVelocityY
  • moveToX
  • moveToY
  • quantity
  • rotate
  • scaleX
  • scaleY
  • speedX
  • speedY
  • tint
  • x
  • y

Which means you can now directly access, modify and tween any of the above emitter properties at run-time while the emitter is active.

Another potentially breaking change is the removal of two internal private counters. These should never have been used directly anyway, but they are:

  • ParticleEmitter._counter - Now available via ParticleEmitter.flowCounter
  • ParticleEmitter._frameCounter - Now available via ParticleEmitter.frameCounter
  • EmitterOp._onEmit is a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyEmit method, to ensure that the Emitter current property remains current.
  • EmitterOp._onUpdate is a new private reference to the update callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyUpdate method, to ensure that the Emitter current property remains current.
  • EmitterOp.destroy is a new method that nulls all references. This is called automatically when a ParticleEmitter is itself destroyed.

Further Particle System Updates and Fixes:

  • The Particle DeathZone.willKill method now takes a Particle instance as its only parameter, instead of x and y coordinates, allowing you to perform more complex checks before deciding if the Particle should be killed, or not.
  • The Particle.resetPosition method has been renamed to setPosition and it now takes optional x/y parameters. If not given, it performs the same task as resetPosition did in earlier versions.
  • The ParticleEmitter class now has the AlphaSingle Component. This allows you to call setAlpha on the Emitter instance itself and have it impact all particles being rendered by it, allowing you to now 'fade in/out' a whole Emitter.
  • Setting frequency wasn't working correctly in earlier versions. It should allow you to specify a time, in ms, between which each 'quantity' of particles is emitted. However, the preUpdate loop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles.
  • Calling ParticleEmitter.start wouldn't reset the _frameCounter value internally, meaning the new emission didn't restart from the first texture frame again.
  • ParticleEmitter.counters is a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous _counter and _frameCounter properties have been merged into this array, along with new ones required for new features.
  • The WebGL Renderer will now use the new setQuad feature of the Transform Matrix. This vastly reduces the amount of math and function calls per particle, from 8 down to 1, increasing performance.
  • Particles with a scaleX or scaleY value of zero will no longer be rendered.
  • ParticleEmitter.preDestroy is a new method that will now clean-up all resources and internal arrays and destroy all Particles that the Emitter owns and clean-up all external references.
  • Particle.destroy is a new method that will clean up all external references and destroy the Animation State controller.
  • The ParticleEmitter._frameLength property is now specified on the class, rather than added dynamically at run-time, helping preserve class shape.
  • The ParticleEmitter.defaultFrame property has been removed as it's not required.
  • Calling ParticleEmitter.setFrame no longer resets the internal _frameCounter value to zero. Instead, the counter comparison has been hardened to >= instead of === to allow this value to change mid-emission and never reach the total.
  • The ParticleEmitter.configFastMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • The ParticleEmitter.configOpMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • Particle.scene is a new property that references the Scene the Particle Emitter belongs to.
  • Particle.anims is a new property that is an instance of the AnimationState component.
  • Particle.emit is a new proxy method that passes all Animation related events through to the Particle Emitter Manager to emit, as Particles cannot emit events directly.
  • Particle.isCropped is a new read-only property. Do not modify.
  • Particle.setSizeToFrame is a new internal NOOP method. Do not call.
  • ParticleEmitter.anims is a new property that contains the Animation keys that can be assigned to Particles.
  • ParticleEmitter.currentAnim is a new property that contains the index of the current animation, as tracked in cycle playback.
  • ParticleEmitter.randomAnim is a new boolean property that controls if the animations are selected randomly, or in a cycle.
  • ParticleEmitter.animQuantity is a new property that controls the number of consecutive particles that are emitted with the current animation.
  • ParticleEmitter.counters is a new internal Float32Array that holds all the counters the Emitter uses.
  • ParticleEmitter.getAnim is a new method, called by Particles when they are emitted, that will return the animation to use, if any.
  • ParticleEmitter.setAnim is a new method, called with the Emitter Manager, that sets the animation data into the Emitter.
  • The Particles.EmitterOp.toJSON method will now JSON stringify the property value before returning it.
  • Particles.EmitterOp.method is a new property that holds the current operation method being used. This is a read-only numeric value.
  • Particles.EmitterOp.active is a new boolean property that defines if the operator is alive, or not. This is now used by the Emitter instead of nulling Emitter properties, helping maintain class shape.
  • Particles.EmitterOp.getMethod is a new internal method that returns the operation function being used as a numeric value. This is then cached in the method property.
  • The Particles.EmitterOp.setMethods method has been updated so it now has a non-optional 'method' parameter. It has also been rewritten to be much more efficient, now being just a single simple select/case block.
  • The Particles.EmitterOp.onChange method will now use the cached 'method' property to avoid running through the setMethods function if not required, allowing each Particle EmitterOp to skip a huge chunk of code.
  • We've also greatly improved the documentation around the Particle classes.
  • ParticleEmitter.setConfig is a new method that allows you to set the configuration of the Emitter. Previously this was known as fromJSON.
  • The ParticleEmitter.setPosition method no longer changes the position of the particle emission point, but of the Emitter itself.
  • The ParticleEmitter.setBounds method has been renamed to setParticleBounds.
  • The ParticleEmitter.setSpeed method has been renamed to setParticleSpeed.
  • The ParticleEmitter.setScale method has been renamed to setParticleScale as setScale will now set the scale of the whole Emitter.
  • The ParticleEmitter.setScaleX and setScaleY methods have been removed. Please use setParticleScale.
  • The ParticleEmitter.setGravity method has been renamed to setParticleGravity.
  • The ParticleEmitter.setGravityX and setGravityY methods have been removed. Please use setParticleGravity.
  • The ParticleEmitter.setAlpha method has been renamed to setParticleAlpha as setAlpha will now set the alpha of the whole Emitter.
  • The ParticleEmitter.setTint method has been renamed to setParticleTint.
  • The ParticleEmitter.setLifespan method has been renamed to setParticleLifespan.
  • The ParticleEmitter.on property has been renamed to emitting to avoid conflicts with the Event Emitter.
  • The ParticleEmitter.x property has been renamed to particleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.y property has been renamed to particleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleX property has been renamed to particleScaleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleY property has been renamed to particleScaleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.tint property has been renamed to particleTint and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.alpha property has been renamed to particleAlpha and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.angle property has been renamed to particleAngle and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.rotate property has been renamed to particleRotate and is a new EmitterOp capable of being tweened.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

TODO

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

  • The RenderTarget class will now create a Framebuffer that includes a Depth Stencil Buffer attachment by default. Previously, it didn't. By attaching a stencil buffer it allows things like Geometry Masks to work in combination with Post FX and other Pipelines. Fix #5802 (thanks @mijinc0)
  • When calling PipelineManager.clear and rebind it will now check if the vao extension is available, and if so, it'll bind a null vertex array. This helps clean-up from 3rd party libs that don't do this directly, such as ThreeJS.
  • The mipmapFilter property in the Game Config now defaults to '' (an empty string) instead of 'LINEAR'. The WebGLRenderer has been updated so that it will no longer create mipmaps at all with a default config. This potential saves a lot of VRAM (if your game has a lot of power-of-two textures) where before it was creating mipmaps that may never have been used. However, you may notice scaling doesn't look as crisp as it did before if you were using this feature without knowing it. To get it back, just add mipmapFilter: 'LINEAR' to your game config. Remember, as this is WebGL1 it only works with power-of-two sized textures.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • The batchLine method in the Multi Pipeline will now check to see if the dxdy len is zero, and if so, it will abort drawing the line. This fixes issues on older Android devices, such as the Samsung Galaxy S6 or Kindle 7, where it would draw erroneous lines leading up to the top-left of the canvas under WebGL when rendering a stroked rounded rectangle. Fix #5429 (thanks @fkoch-tgm @sreadixl)
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light fragment shader will now use the outTintEffect attribute meaning the Light Pipeline will now correctly light both tinted and fill-tinted Game Objects. Fix #5452 (thanks @kainage)
  • The Light Pipeline will now check to see if a Light2D enabled Game Object has a parent Container, or not, and factor the rotation and scale of this into the light calculation. Fix #6086 (thanks @irongaze)
  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.19

We have updated the version of Matter Physics to the latest v0.19 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Improves general consistency of results between different timesteps based on 60hz as a baseline
  • Changes Body.setAngularVelocity and Body.setVelocity functions to be timestep independent
  • Adds timestep independent Body.setSpeed, Body.setAngularSpeed, Body.getSpeed, Body.getVelocity and Body.getAngularVelocity
  • Adds optional updateVelocity argument to Body.setPosition, Body.setAngle, Body.translate and Body.rotate
  • Removes correction parameter from Engine.update as it is now built-in
  • Changed Body.setAngularVelocity and Body.setVelocity to be timestep independent
  • Improved similarity of results between different timesteps based on 60hz as a baseline
  • Added timestep independent Body.setSpeed, Body.setAngularSpeed, Body.getSpeed, Body.getVelocity, Body.getAngularVelocity
  • Added optional updateVelocity argument to Body.setPosition, Body.setAngle, Body.translate, Body.rotate
  • Added extended documentation for Body.applyForce
  • Moved time correction feature from Engine.update to be built-in to Matter.Body
  • Added readonly body.deltaTime property
  • Added speed setters to Body.set
  • Added updateVelocity argument to Body.setPosition, Body.setAngle, Body.translate and Body.rotate
  • Changed engine collisionStart event to trigger after resolving and after updating body velocities
  • Derive velocity from position in setters
  • Fixed issues with engine event.delta
  • Handle null constraint points in Constraint.pointAWorld and Constraint.pointBWorld
  • Improved Body.applyForce docs
  • Improved delta factors in resolver and constraint stiffness
  • Improved Matter.Body docs for functions and properties including readonly
  • Improved Matter.Engine docs
  • Improved delta consistency
  • Removed render element warning
  • Removed unused delta params
  • Updated body velocity properties after resolving
  • Updated timing improvements
  • Used Body.getVelocity in Matter.Render
  • Used speed getter in Matter.Sleeping and Matter.Render

Notes

When using a fixed timestep of 60hz (~16.666ms engine delta) results should look similar to before, as this was taken as the baseline.

If you're using a non-fixed timestep or one other than 60hz (~16.666ms) results should now become more similar to the 60hz baseline, therefore you may need to adjust e.g. body and constraint properties.

Since Body.setAngularVelocity and Body.setVelocity are now timestep independent, you may need to adjust code you may have been using that factored in the timestep.

For timestep independence, the Matter.Body speed and velocity getter and setter functions now relate to a fixed time unit rather than timestep, currently set as 1000/60 for easier backwards compatibility at the baseline 60hz.

Note that Body.applyForce naturally still remains timestep dependent as before, see the updated Body.applyForce docs for details.

While the properties body.velocity and body.speed (and angular versions) still exist they are not typically recommended for user code, in most cases you should switch to the new Body.getVelocity and Body.getSpeed functions as they are timestep independent.

The following changes came from the v0.18 release, which are also part of v0.19:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

Because of the changes above, the following new methods are available to any Phaser Matter Physics Game Object:

  • getVelocity - Returns the current linear velocity of the Body as a Vec2.
  • getAngularVelocity - Returns the current rotation velocity of the Body.
  • setAngularSpeed - Sets the current rotational speed of the body. Direction is maintained. Affects body angular velocity.
  • getAngularSpeed - Returns the current rotational speed of the body. Equivalent to the magnitude of its angular velocity.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been rewritten to help with performance, resolve some of its lingering issues and unifies the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • The Tween.seek method used to take a value between 0 and 1, based on how far through the Tween you wished to seek. However, it did not work with infinitely looping or repeating Tweens and would crash the browser tab. The new seek method takes a value in milliseconds instead and works perfectly on infinite Tweens.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as the source for a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • origin is now (0.5, 0.5) by default instead of (0, 0).

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Post Pipeline Updates

In order to add clarity in the codebase we have created a new PostPipeline Component and moved all of the relevant functions from the Pipeline component in to it. This leads to the following changes:

  • PostPipeline is a new Game Object Component that is now inherited by all Game Objects that are capable of using it.
  • Game Objects with the PostPipeline component now have a new property called postPipelineData. This object is used for storing Post Pipeline specific data in. Previously, both regular and post pipelines used the same pipelineData object, but this has now been split up for flexibility.
  • The Pipeline.resetPipeline method no longer has its first resetPostPipelines argument. It now has just one argument resetData so please be aware of this if you call this function anywhere in your code.
  • PostPipeline.initPostPipeline is a new method that should be called by any Game Object that supports Post Pipelines.
  • The following Game Objects now have the new PostPipeline Component exclusively: Container and Layer.

Input System Updates

There are breaking changes from previous versions of Phaser.

  • The InteractiveObject.alwaysEnabled property has been removed. It is no longer checked within the InputPlugin and setting it will have no effect. This property has not worked correctly since version 3.52 when the new render list was implemented. Upon further investigation we decided to remove the property entirely, rather than shoe-horn it into the render list. If you need to create a non-rendering Interactive area, use the Zone Game Object instead.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.
  • The GameObjects.Components.Mask.createBitmapMask method can now accept the x, y, texture and frame parameters new to the BitmapMask constructor.
  • Previously, calling createBitmapMask on a Shape Game Object would fail unless you passed the shape to the method. Now, it will correctly create a mask from the Shape without needing to pass it. Fix #5976 (thanks @samme)

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • The Hexagonal Tilemap system now supports all 4 different types of layout as offered by Tiled: staggeraxis-y + staggerindex-odd, staggeraxis-x + staggerindex-odd, staggeraxis-y + staggerindex-even and staggeraxis-x, staggerindex-even (thanks @rexrainbow)
  • The Arcade Physics World has a new property tileFilterOptions which is an object passed to the GetTilesWithin methods used by the Sprite vs. Tilemap collision functions. These filters dramatically reduce the quantity of tiles being checked for collision, potentially saving thousands of redundant math comparisons from taking place.
  • The Graphics.strokeRoundedRect and fillRoundedRect methods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow)
  • AnimationManager.getAnimsFromTexture is a new method that will return all global Animations, as stored in the Animation Manager, that have at least one frame using the given Texture. This will not include animations created directly on local Sprites.
  • BitmapText.setLineSpacing is a new method that allows you to set the vertical spacing between lines in multi-line BitmapText Game Objects. It works in the same was as spacing for Text objects and the spacing value can be positive or negative. See also BitmapText.lineSpacing for the property rather than the method.
  • WebGLPipeline.vertexAvailable is a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.
  • The Tilemap and TilemapLayer classes have a new method getTileCorners. This method will return an array of Vector2s with each entry corresponding to the corners of the requested tile, in world space. This currently works for Orthographic and Hexagonal tilemaps.
  • BaseSoundManager.getAllPlaying is a new method that will return all currently playing sounds in the Sound Manager.
  • Animation.showBeforeDelay is a new optional boolean property you can set when creating, or playing an animation. If the animation has a delay before playback starts this controls if it should still set the first frame immediately, or after the delay has expired (the default).
  • InputPlugin.resetPointers is a new method that will loop through all of the Input Manager Pointer instances and reset them all. This is useful if a 3rd party component, such as Vue, has stolen input from Phaser and you need to reset its input state again.
  • Pointer.reset is a new method that will reset a Pointer instance back to its 'factory' settings.
  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • Game.isPaused is a new boolean that tracks if the Game loop is paused, or not (and can also be toggled directly)
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • You will now get a warning from the AnimationManager and AnimationState if you try to add an animation with a key that already exists. Fix #6434.
  • Tilemap.addTilesetImage has a new optional parameter tileOffset which, if given, controls the rendering offset of the tiles. This was always available on the Tileset itself, but not from this function (thanks @imothee)
  • The GameObject.getBounds method will now return a Geom.Rectangle instance, rather than a plain Object (thanks @samme)
  • The GetBounds.getCenter method now has an optional includeParent argument, which allows you to get the value in world space.
  • The MatterTileBody class, which is created when you convert a Tilemap into a Matter Physics world, will now check to see if the Tile has flipX or flipY set on it and rotate the body accordingly. Fix #5893 (thanks @Olliebrown @phaserhelp)
  • The BaseCamera has had its Alpha component replaced with AlphaSingle. Previously you had access to properties such as alphaTopLeft that never worked, now it correctly has just a single alpha property (thanks @samme)
  • Time.Clock.startTime is a new property that stores the time the Clock (and therefore the Scene) was started. This can be useful for comparing against the current time to see how much real world time has elapsed (thanks @samme)
  • ColorMatrix._matrix and _data are now Float32Arrays.
  • Calling the ColorMatrix.set, reset and getData methods all now use the built-in Float32 Array operations, making them considerably faster.
  • ColorMatrix.BLACK_WHITE is a new constant used by blackwhite operations.
  • ColorMatrix.NEGATIVE is a new constant used by negative operations.
  • ColorMatrix.DESATURATE_LUMINANCE is a new constant used by desaturation operations.
  • ColorMatrix.SEPIA is a new constant used by sepia operations.
  • ColorMatrix.LSD is a new constant used by LSD operations.
  • ColorMatrix.BROWN is a new constant used by brown operations.
  • ColorMatrix.VINTAGE is a new constant used by vintage pinhole operations.
  • ColorMatrix.KODACHROME is a new constant used by kodachrome operations.
  • ColorMatrix.TECHNICOLOR is a new constant used by technicolor operations.
  • ColorMatrix.POLAROID is a new constant used by polaroid operations.
  • ColorMatrix.SHIFT_BGR is a new constant used by shift BGR operations.
  • If no Audio URLs match the given device a new warning is now displayed in the console (thanks @samme)
  • Texture.has will now return a strict boolean, rather than an object that can be cooerced into a boolean (thanks @samme)
  • The CanvasTexture.draw method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The CanvasTexture.drawFrame method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The CanvasTexture.clear method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The Game.registry, which is a DataManager instance that can be used as a global store of game wide data will now use its own Event Emitter, instead of the Game's Event Emitter. This means it's perfectly safe for you to now use the Registry to emit and listen for your own custom events without conflicting with events the Phaser Game instance emits.
  • The GenerateVerts function has a new optional parameter flipUV which, if set, will flip the UV texture coordinates (thanks cedarcantab)
  • The GenerateVerts function no longer errors if the verts and uvs arrays are not the same size and containsZ is true (thanks cedarcantab)
  • The Device.Browser checks for Opera and Edge have been updated to use the more modern user agent strings those browsers now use. This breaks compatibility with really old versions of those browsers but fixes it for modern ones (which is more important) (thanks @ ArtemSiz)
  • The SceneManager.processQueue method will no longer return if a new Scene was added, after starting it. This allows any other queued operations to still be run in the same frame, rather than being delayed until the next game frame. Fix #5359 (thanks @telinc1)
  • Camera.scrollX and scrollY will now only set the Camera.dirty flag to true if the new value given to them is different from their current value. This allows you to use this property in your own culling functions. Fix #6088 (thanks @Waclaw-I)
  • Face.update is a new method that updates each of the Face vertices. This is now called internally by Face.isInView.
  • Vertex.resize is a new method that will set the position and then translate the Vertex based on an identity matrix.
  • The Vertex.update method now returns this to allow it to be chained.
  • You can now optionally specify the maxSpeed value in the Arcade Physics Group config (thanks @samme)
  • You can now optionally specify the useDamping boolean in the Arcade Physics Group config (thanks @samme)
  • Removed the HexagonalTileToWorldY function as it cannot work without an X coordinate. Use HexagonalTileToWorldXY instead.
  • Removed the HexagonalWorldToTileY function as it cannot work without an X coordinate. Use HexagonalWorldToTileXY instead.
  • Earcut has been updated to version 2.2.4. This release improves performance by 10-15% and fixes 2 rare race conditions that could leave to infinite loops. Earcut is used internally by Graphics and Shape game objects when triangulating polygons for complex shapes.
  • The BaseSoundManager.getAll method used to require a key parameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned.
  • The WebAudioSoundManager will now detect if the Audio Context enters a 'suspended' or 'interrupted' state as part of its update loop and if so it'll try to resume the context. This can happen if you change or disable the audio device, such as plugging in headphones with built-in audio drivers then disconnecting them, or swapping tabs on iOS. Fix #5353 (thanks @helloyoucan)
  • The CONTEXT_RESTORED Game Event has been removed and the WebGL Renderer no longer listens for the contextrestored DOM event, or has a contextRestoredHandler method. This never actually worked properly, in any version of Phaser 3 - although the WebGLRenderer would be restored, none of the shaders, pipelines or textures were correctly re-created. If a context is now lost, Phaser will display an error in the console and all rendering will halt. It will no longer try to re-create the context, leading to masses of WebGL errors in the console. Instead, it will die gracefully and require a page reload.
  • The Text and TileSprite Game Objects no longer listen for the CONTEXT_RESTORED event and have had their onContextRestored methods removed.
  • Scenes.Systems.canInput is a new internal method that determines if a Scene can receive Input events, or not. This is now used by the InputPlugin instead of the previous isActive test. This allows a Scene to emit and handle input events even when it is running init or preload. Previously, it could only do this after create had finished running. Fix #6123 (thanks @yaasinhamidi)
  • The BitmapText Game Object has two new read-only properties displayWidth and displayHeight. This allows the BitmapText to correctly use the GetBounds component.
  • The BitmapText Game Object now has the GetBounds component added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames)
  • WebGLSnapshot will now flip the pixels in the created Image element if the source was a framebuffer. This means grabbing a snapshot from a Dynamic or Render Texture will now correctly invert the pixels on the y axis for an Image. Grabbing from the game renderer will skip this.
  • WebGLRenderer.snapshotFramebuffer and by extension, the snapshot methods in Dynamic Textures and Render Textures, has been updated to ensure that the width and height never exceed the framebuffer dimensions, or it'll cause a runtime error. The method snapshotArea has had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)
  • Animation.stop is always called when a new animation is loaded, regardless if the animation was playing or not and the delayCounter is reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)
  • ScaleManager.listeners has been renamed to domlisteners to avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)
  • Geom.Intersects.LineToLine will no longer create an internal Point object, as it's not required internally (thanks @Trissolo)
  • The tempZone used by GridAlign has now had setOrigin(0, 0) applied to it. This leads to more accurate / expected zone placement when aligning grid items.
  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now

- JavaScript
Published by photonstorm about 3 years ago

phaser - Phaser v3.60.0 Beta 22

Version 3.60.0 - Miku - in development

New Features - Timeline Class

Phaser 3.60 has a new Timeline Class which allows for fine-grained control of sequenced events. Previously in 3.55 the Timeline was part of the Tween system and it never quite worked as intended. In 3.60 it has been removed from Tweens entirely, replaced with the much more solid and reliable Tween Chains and Timeline has now becomes its own first-class citizen within Phaser. It allows you to sequence any event you like, not just tweens.

A Timeline is a way to schedule events to happen at specific times in the future. You can think of it as an event sequencer for your game, allowing you to schedule the running of callbacks, events and other actions at specific times in the future.

A Timeline is a Scene level system, meaning you can have as many Timelines as you like, each belonging to a different Scene. You can also have multiple Timelines running at the same time.

If the Scene is paused, the Timeline will also pause. If the Scene is destroyed, the Timeline will be automatically destroyed. However, you can control the Timeline directly, pausing, resuming and stopping it at any time.

Create an instance of a Timeline via the Game Object Factory:

js const timeline = this.add.timeline();

The Timeline always starts paused. You must call play on it to start it running.

You can also pass in a configuration object on creation, or an array of them:

```js const timeline = this.add.timeline({ at: 1000, run: () => { this.add.sprite(400, 300, 'logo'); } });

timeline.play(); ```

In this example we sequence a few different events:

```js const timeline = this.add.timeline([ { at: 1000, run: () => { this.logo = this.add.sprite(400, 300, 'logo'); }, sound: 'TitleMusic' }, { at: 2500, tween: { targets: this.logo, y: 600, yoyo: true }, sound: 'Explode' }, { at: 8000, event: 'HURRY_PLAYER', target: this.background, set: { tint: 0xff0000 } } ]);

timeline.play(); ```

There are lots of options available to you via the configuration object. See the TimelineEventConfig typedef for more details.

New Features - ESM Support

Phaser 3.60 uses the new release of Webpack 5 in order to handle the builds. The configurations have been updated to follow the new format this upgrade introduced. As a bonus, Webpack 5 also bought a new experimental feature called 'output modules', which will take a CommonJS code-base, like Phaser uses and wrap the output in modern ES Module declarations.

We are now using this as part of our build. You will find in the dist folder a new phaser.esm.js file, which is also linked in from our package.json module property. Using this build you can access any of the Phaser modules directly via named imports, meaning you can code like this:

```js import { AUTO, Scene, Game } from './phaser.esm.js';

class Test extends Scene { constructor () { super(); }

create ()
{
    this.add.text(10, 10, 'Welcome to Phaser ESM');
}

}

const config = { type: AUTO, width: 800, height: 600, parent: 'phaser-example', scene: [ Test ] };

const game = new Game(config); ```

Note that we're importing from the local esm bundle. By using this approach you don't need to even use a bundler for quick local prototyping or testing, you can simply import and code directly.

The dist folder still also contains phaser.js which, as before, uses a UMD export.

Because the Webpack feature is experimental we won't make the ESM version the default just yet, but if you're curious and want to explore, please go ahead!

New Features - Built-in Special FX

We have decided to bundle a selection of highly flexible special effect shaders in to Phaser 3.60 and provide access to them via an easy to use set of API calls. The FX included are:

  • Barrel - A nice pinch / bulge distortion effect.
  • Bloom - Add bloom to any Game Object, with custom offset, blur strength, steps and color.
  • Blur - 3 different levels of gaussian blur (low, medium and high) and custom distance and color.
  • Bokeh / TiltShift - A bokeh and tiltshift effect, with intensity, contrast and distance settings.
  • Circle - Add a circular ring around any Game Object, useful for masking / avatar frames, with custom color, width and background color.
  • ColorMatrix - Add a ColorMatrix to any Game Object with access to all of its methods, such as sepia, greyscale, lsd and lots more.
  • Displacement - Use a displacement texture, such as a noise texture, to drastically (or subtly!) alter the appearance of a Game Object.
  • Glow - Add a smooth inner or outer glow, with custom distance, strength and color.
  • Gradient - Draw a gradient between two colors across any Game Object, with optional 'chunky' mode for classic retro style games.
  • Pixelate - Make any Game Object appear pixelated, to a varying degree.
  • Shadow - Add a drop shadow behind a Game Object, with custom depth and color.
  • Shine - Run a 'shine' effect across a Game Object, either additively or as part of a reveal.
  • Vignette - Apply a vignette around a Game Object, with custom offset position, radius and color.
  • Wipe - Set a Game Object to 'wipe' or 'reveal' with custom line width, direction and axis of the effect.

What's more, the FX can be stacked up. You could add, for example, a Barrel followed by a Blur and then topped-off with a Circle effect. Just by adjusting the ordering you can achieve some incredible and unique effects, very quickly.

We've worked hard to make the API as easy to use as possible, too. No more messing with pipelines or importing plugins. You can simply do:

```js const player = this.add.sprite(x, y, texture);

player.preFX.addGlow(0xff0000, 32); ```

This will add a 32 pixel red glow around the player Sprite.

Each effect returns a new FX Controller instance, allowing you to easily adjust the special effects in real-time via your own code, tweens and similar:

```js const fx = container.postFX.addWipe();

this.tweens.add({ targets: fx, progress: 1 }); ```

This will add a Wipe Effect to a Container instance and then tween its progress value from 0 to 1, causing the wipe to play out.

All texture-based Game Objects have access to Pre FX (so that includes Images, Sprites, TileSprites, Text, RenderTexture and Video). However, all Game Objects have access to Post FX, as do cameras. The difference is just when the effect is applied. For a 'pre' effect, it is applied before the Game Object is drawn. For a 'post' effect, it's applied after it has been drawn. All of the same effects are available to both.

js this.cameras.main.postFX.addTiltShift();

For example, this will apply a Tilt Shift effect to everything being rendered by the Camera. Which is a much faster way of doing it than applying the same effect to every child in a Scene. You can also apply them to Containers, allowing more fine-grained control over the display.

The full list of new methods are as follows:

Available only to texture-based Game Objects:

  • GameObject.preFX.addGlow adds a Glow Pre FX effect to the Game Object.
  • GameObject.preFX.addShadow adds a Shadow Pre FX effect to the Game Object.
  • GameObject.preFX.addPixelate adds a Pixelate Pre FX effect to the Game Object.
  • GameObject.preFX.addVignette adds a Vignette Pre FX effect to the Game Object.
  • GameObject.preFX.addShine adds a Shine Pre FX effect to the Game Object.
  • GameObject.preFX.addBlur adds a Blur Pre FX effect to the Game Object.
  • GameObject.preFX.addGradient adds a Gradient Pre FX effect to the Game Object.
  • GameObject.preFX.addBloom adds a Bloom Pre FX effect to the Game Object.
  • GameObject.preFX.addColorMatrix adds a ColorMatrix Pre FX effect to the Game Object.
  • GameObject.preFX.addCircle adds a Circle Pre FX effect to the Game Object.
  • GameObject.preFX.addBarrel adds a Barrel Pre FX effect to the Game Object.
  • GameObject.preFX.addDisplacement adds a Displacement Pre FX effect to the Game Object.
  • GameObject.preFX.addWipe adds a Wipe Pre FX effect to the Game Object.
  • GameObject.preFX.addReveal adds a Reveal Pre FX effect to the Game Object.
  • GameObject.preFX.addBokeh adds a Bokeh Pre FX effect to the Game Object.
  • GameObject.preFX.addTiltShift adds a TiltShift Pre FX effect to the Game Object.

Available to all Game Objects:

  • GameObject.postFX.addGlow adds a Glow Post FX effect to the Game Object.
  • GameObject.postFX.addShadow adds a Shadow Post FX effect to the Game Object.
  • GameObject.postFX.addPixelate adds a Pixelate Post FX effect to the Game Object.
  • GameObject.postFX.addVignette adds a Vignette Post FX effect to the Game Object.
  • GameObject.postFX.addShine adds a Shine Post FX effect to the Game Object.
  • GameObject.postFX.addBlur adds a Blur Post FX effect to the Game Object.
  • GameObject.postFX.addGradient adds a Gradient Post FX effect to the Game Object.
  • GameObject.postFX.addBloom adds a Bloom Post FX effect to the Game Object.
  • GameObject.postFX.addColorMatrix adds a ColorMatrix Post FX effect to the Game Object.
  • GameObject.postFX.addCircle adds a Circle Post FX effect to the Game Object.
  • GameObject.postFX.addBarrel adds a Barrel Post FX effect to the Game Object.
  • GameObject.postFX.addDisplacement adds a Displacement Post FX effect to the Game Object.
  • GameObject.postFX.addWipe adds a Wipe Post FX effect to the Game Object.
  • GameObject.postFX.addReveal adds a Reveal Post FX effect to the Game Object.
  • GameObject.postFX.addBokeh adds a Bokeh Post FX effect to the Game Object.
  • GameObject.postFX.addTiltShift adds a TiltShift Post FX effect to the Game Object.

New Features - Spatial Sound

Thanks to a contribution from @alxwest the Web Audio Sound system now supports spatial sound.

TODO - List all of the new properties and methods!

New Features - Spine 4 Support

Thanks to a contribution from @justintien we now have a Spine 4 Plugin available.

You can find it in the plugins/spine4.1 folder in the main repository. There are also a bunch of new npm scripts to help build this plugin:

npm run plugin.spine4.1.full.dist - To build new dist files for both canvas and WebGL. npm run plugin.spine4.1.dist - To build new dist files. npm run plugin.spine4.1.watch - To enter watch mode when doing dev work on the plugin. npm run plugin.spine4.1.runtimes - To build new versions of the Spine 4 runtimes.

The core plugin API remains largely the same. You can find lots of updated examples in the Phaser 3 Examples repo in the 3.60/spine4.1 folder.

We will maintain both the Spine 3 and 4 plugins for the forseeable future.

Additional Spine 3 Bug Fixes

  • Using drawDebug on a Spine Game Object to view its skeleton would cause the next object in the display list to be skipped for rendering, if it wasn't a Spine Game Object too. This is because the Spine 3 skeleton debug draw ends the spine batch but the Scene Renderer wasn't rebound. Fix #6380 (thanks @spayton)
  • The Spine Plugin add and make functions didn't clear and rebind the WebGL pipeline. This could cause two different visual issues: The first is that a Phaser Game Object (such as a Sprite) could be seen to change its texture to display the Spine atlas texture instead for a single frame, and then on the next pass revert back to normal again. The second issue is that if the Spine skeleton wasn't added to the display list, but just created (via addToScene: false) then the Sprite would take on the texture frame entirely from that point on. Fix #6362 (thanks @frissonlabs)
  • Previously, it wasn't possible for multiple Spine Atlases to use PNGs with the exact same filename, even if they were in different folders. The SpineFile loader has now been updated so that the always-unique Spine key is pre-pended to the filename, for example if the key was bonus and the PNG in the atlas was coin.png then the final key (as stored in the Texture Manager) is now bonus:coin.png. The SpinePlugin.getAtlasCanvas and getAtlasWebGL methods have been updated to reflect this change. Fix #6022 (thanks @orjandh)
  • If a SpineContainer had a mask applied to it and the next immediate item on the display list was another Spine object (outside of the Container) then it would fail to rebind the WebGL pipeline, causing the mask to break. It will now rebind the renderer at the end of the SpineContainer batch, no matter what, if it has a mask. Fix #5627 (thanks @FloodGames)

New Features - Plane Game Object

Phaser v3.60 contains a new native Plane Game Object. The Plane Game Object is a helper class that takes the Mesh Game Object and extends it, allowing for fast and easy creation of Planes. A Plane is a one-sided grid of cells, where you specify the number of cells in each dimension. The Plane can have a texture that is either repeated (tiled) across each cell, or applied to the full Plane.

The Plane can then be manipulated in 3D space, with rotation across all 3 axis.

This allows you to create effects not possible with regular Sprites, such as perspective distortion. You can also adjust the vertices on a per-vertex basis. Plane data becomes part of the WebGL batch, just like standard Sprites, so doesn't introduce any additional shader overhead. Because the Plane just generates vertices into the WebGL batch, like any other Sprite, you can use all of the common Game Object components on a Plane too, such as a custom pipeline, mask, blend mode or texture.

You can use the uvScroll and uvScale methods to adjust the placement and scaling of the texture if this Plane is using a single texture, and not a frame from a texture atlas or sprite sheet.

The Plane Game Object also has the Animation component, allowing you to play animations across the Plane just as you would with a Sprite.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Nine Slice Game Object

Phaser v3.60 contains a new native Nine Slice Game Object. A Nine Slice Game Object allows you to display a texture-based object that can be stretched both horizontally and vertically, but that retains fixed-sized corners. The dimensions of the corners are set via the parameters to the class. When you resize a Nine Slice Game Object only the middle sections of the texture stretch. This is extremely useful for UI and button-like elements, where you need them to expand to accommodate the content without distorting the texture.

The texture you provide for this Game Object should be based on the following layout structure:

A B +---+----------------------+---+ C | 1 | 2 | 3 | +---+----------------------+---+ | | | | | 4 | 5 | 6 | | | | | +---+----------------------+---+ D | 7 | 8 | 9 | +---+----------------------+---+

When changing this objects width and / or height:

areas 1, 3, 7 and 9 (the corners) will remain unscaled
areas 2 and 8 will be stretched horizontally only
areas 4 and 6 will be stretched vertically only
area 5 will be stretched both horizontally and vertically

You can also create a 3 slice Game Object:

This works in a similar way, except you can only stretch it horizontally. Therefore, it requires less configuration:

A B +---+----------------------+---+ | | | | C | 1 | 2 | 3 | | | | | +---+----------------------+---+

When changing this objects width (you cannot change its height)

areas 1 and 3 will remain unscaled
area 2 will be stretched horizontally

The above configuration concept is adapted from the Pixi NineSlicePlane.

To specify a 3 slice object instead of a 9 slice you should only provide the leftWidth and rightWidth parameters. To create a 9 slice you must supply all parameters.

The minimum width this Game Object can be is the total of leftWidth + rightWidth. 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 scale it.

In terms of performance, using a 3 slice Game Object is the equivalent of having 3 Sprites in a row. Using a 9 slice Game Object is the equivalent of having 9 Sprites in a row. The vertices of this object are all batched together and can co-exist with other Sprites and graphics on the display list, without incurring any additional overhead.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Pre FX Pipeline

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isPreFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Pre FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all PreFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Pre FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.
  • The WebGLPipeline.setTime method has a new optional parameter shader, which allows you to control the shader on which the time value is set.
  • If you add #define SHADER_NAME to the start of your shader then it will be picked up as the WebGLShader name during the setShadersFromConfig process within WebGLPipeline.
  • Calling setPostPipeline on a Game Object will now pass the pipelineData configuration object (if provided) to the pipeline instance being created.
  • PipelineManager.getPostPipeline now has an optional 3rd parameter, a config object that is passed to the pipeline instance in its constructor, which can be used by the pipeline during its set-up.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Updated Particle System

The Particle system has been mostly rewritten to give it a much needed overhaul. This makes the API cleaner, the Game Objects a lot more memory efficient and also introduces several great new features. In order to do this, we had to make some breaking changes. The largest being the way in which particles are now created.

Previously when you used the this.add.particles command it would create a ParticleEmitterManager instance. You would then use this to create an Emitter, which would actually emit the particles. While this worked and did allow a Manager to control multiple emitters we found that in discussion developers seldom used this feature and it was common for a Manager to own just one single Emitter.

In order to streamline memory and the display list we have removed the ParticleEmitterManager entirely. When you call this.add.particles you're now creating a ParticleEmitter instance, which is being added directly to the display list and can be manipulated just like any other Game Object, i.e. scaled, rotated, positioned, added to a Container, etc. It now extends the GameObject base class, meaning it's also an event emitter, which allowed us to create some handy new events for particles.

So, to create an emitter, you now give it an xy coordinate, a texture and an emitter configuration object (you can also set this later, but most commonly you'd do it on creation). I.e.:

js const emitter = this.add.particles(100, 300, 'flares', { frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

This will create a 'red flare' emitter at 100 x 300.

Prior to 3.60 it would have looked like:

```js const manager = this.add.particles('flares');

const emitter = manager.createEmitter({ x: 100, y: 300, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 }); ```

The change is quite subtle but makes a big difference internally.

The biggest real change is with the particle x/y coordinates. It's important to understand that if you define x/y coordinates within the emitter configuration, they will be relative to those given in the add.particles call:

js const emitter = this.add.particles(100, 300, 'flares', { x: 100, y: 100, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

In the above example the particles will emit from 200 x 400 in world space, because the emitter is at 100 x 300 and the particles emit from an offset of 100 x 100.

By making this change it now means you're able to do things like tween the x/y coordinates of the emitter (something you couldn't do before), or add a single emitter to a Container.

Other new features include:

Animated Particles

The Particle class now has an instance of the Animation State component within it. This allows a particle to play an animation when it is emitted, simply by defining it in the emitter config.

For example, this will make each particle play the 'Prism' animation on emission:

js const emitter = this.add.particles(400, 300, 'gems', { anim: 'prism' ... });

You can also allow it to select a random animation by providing an array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: [ 'prism', 'square', 'ruby', 'square' ] ... });

You've also the ability to cycle through the animations in order, so each new particle gets the next animation in the array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'square', 'ruby', 'square' ], cycle: true } ... });

Or even set a quantity. For example, this will emit 10 'prism' particles, then 10 'ruby' particles and then repeat:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'ruby' ], cycle: true, quantity: 10 } ... });

The Animations must have already been created in the Global Animation Manager and must use the same texture as the one bound to the Particle Emitter. Aside from this, you can still control them in the same way as any other particle - scaling, tinting, rotation, alpha, lifespan, etc.

Fast Forward Particle Time

  • You can now 'fast forward' a Particle Emitter. This can be done via either the emitter config, using the new advance property, or by calling the new ParticleEmitter.fastForward method. If, for example, you have an emitter that takes a few seconds to 'warm up' and get all the particles into position, this allows you to 'fast forward' the emitter to a given point in time. The value is given in ms. All standard emitter events and callbacks are still handled, but no rendering takes place during the fast-forward until it has completed.
  • The ParticleEmitter.start method has a new optional parameter advance that allows you to fast-forward the given amount of ms before the emitter starts flowing.

Particle Interpolation

  • It's now possible to create a new Interpolation EmitterOp. You do this by providing an array of values to interpolate between, along with the function name:

js const emitter = this.add.particles(0, 0, 'texture', { x: { values: [ 50, 500, 200, 800 ], interpolation: 'catmull' } ... });

This will interpolate the x property of each particle through the data set given, using a catmull rom interpolation function. You can also use linear or bezier functions. Interpolation can be combined with an ease type, which controls the progression through the time value. The related EmitterOpInterpolationConfig types have also been added.

Particle Emitter Duration

  • The Particle Emitter config has a new optional parameter duration:

js const emitter = this.add.particles(0, 0, 'texture', { speed: 24, lifespan: 1500, duration: 500 });

This parameter is used for 'flow' emitters only and controls how many milliseconds the emitter will run for before automatically turning itself off.

  • ParticleEmitter.duration is a new property that contains the duration that the Emitter will emit particles for in flow mode.
  • The ParticleEmitter.start method has a new optional parameter duration, which allows you to set the emitter duration when you call this method. If you do this, it will override any value set in the emitter configuration.
  • The ParticleEmitter.stop method has a new optional parameter kill. If set it will kill all alive particles immediately, rather than leaving them to die after their lifespan expires.

Stop After a set number of Particles

  • The Particle Emitter config has a new optional stopAfter property. This, combined with the frequency property allows you to control exactly how many particles are emitted before the emitter then stops:

js const emitter = this.add.particles(0, 0, 'texture', { x: { start: 400, end: 0 }, y: { start: 300, end: 0 }, lifespan: 3000, frequency: 250, stopAfter: 6, quantity: 1 });

In the above code the emitter will launch 1 particle (set by the quantity property) every 250 ms (set by the frequency property) and move it to xy 0x0. Once it has fired 6 particles (the stopAfter property) the emitter will stop and emit the COMPLETE event.

  • The stopAfter counter is reset each time you call the start or flow methods.

Particle Hold

  • You can configure a Particle to be frozen or 'held in place' after it has finished its lifespan for a set number of ms via the new hold configuration option:

js const emitter = this.add.particles(0, 0, 'texture', { lifespan: 2000, scale: { start: 0, end: 1 }, hold: 1000 ... });

The above will scale a Particle in from 0 to 1 over the course of its lifespan (2 seconds). It will then hold it on-screen for another second (1000 ms) before the Emitter recycles it and removes it from display.

Particle Emitter Events

  • The Particle Emitter will now fire 5 new events. Listen for the events as follows:

```js const emitter = this.add.particles(0, 0, 'flares');

emitter.on('start', (emitter) => { // emission started });

emitter.on('explode', (emitter, particle) => { // emitter 'explode' called });

emitter.on('deathzone', (emitter, particle, deathzone) => { // emitter 'death zone' called });

emitter.on('stop', (emitter) => { // emission has stopped });

emitter.on('complete', (emitter) => { // all particles fully dead }); ```

  • The Particles.Events.START event is fired whenever the Emitter begins emission of particles in flow mode. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.EXPLODE event is fired whenever the Emitter explodes a bunch of particles via the explode method. A reference to the ParticleEmitter and a reference to the most recently fired Particle instance are the two parameters.
  • The Particles.Events.DEATH_ZONE event is fired whenever a Particle is killed by a Death Zone. A reference to the ParticleEmitter, the killed Particle and the DeathZone that caused it are the 3 parameters.
  • The Particles.Events.STOP event is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call the stop method, or when an Emitter hits its duration or stopAfter limit. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.COMPLETE event is fired when the final alive particle expires.

Multiple Emit Zones

  • In v3.60 a Particle Emitter can now have multiple emission zones. Previously, an Emitter could have only a single emission zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addEmitZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addEmitZone({ type: 'edge', source: circle, quantity: 64 }); ```

  • When an Emitter has more than one emission zone, the Particles will cycle through the zones in sequence. For example, an Emitter with 3 zones would emit its first particle from zone 1, the second from zone 2, the third from zone 3, the fourth from zone 1, etc.
  • You can control how many particles are emitted from a single zone via the new total property. EdgeZone.total and RandomZone.total are new properties that control the total number of particles the zone will emit, before passing control over to the next zone in the list, if any. The default is -1.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeEmitZone is a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getEmitZone is a new method that Particles call when they are 'fired' in order to set their starting position, if any.
  • The property ParticleEmitter.emitZone has been removed. It has been replaced with the new ParticleEmitter.emitZones array-based property.

Multiple Death Zones

  • In v3.60 a Particle Emitter can now have multiple death zones. Previously, an Emitter could have only a single death zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addDeathZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addDeathZone({ type: 'onEnter', source: circle }); ```

  • When an Emitter has more than one Death Zone, the Particles will check themselves against all of the Death Zones, to see if any of them kills them.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeDeathZone is a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getDeathZone is a new method that Particles call when they are updated in order to check if they intersect with any of the Death Zones.
  • The property ParticleEmitter.deathZone has been removed. It has been replaced with the new ParticleEmitter.deathZones array-based property.

Particle Colors

  • You can now specify a new color property in the Emitter configuration. This takes the form of an array of hex color values that the particles will linearly interpolate between during theif lifetime. This allows you to now change the color of a particle from birth to death, which gives you far more control over your emitter visuals than ever before. You'd use it as follows:

js const flame = this.add.particles(150, 550, 'flares', { frame: 'white', color: [ 0xfacc22, 0xf89800, 0xf83600, 0x9f0404 ], colorEase: 'quad.out', lifespan: 2400, angle: { min: -100, max: -80 }, scale: { start: 0.70, end: 0, ease: 'sine.out' }, speed: 100, advance: 2000, blendMode: 'ADD' });

Here you can see the array of 4 colors it will interpolate through.

  • The new colorEase configuration property allows you to define the ease used to calculate the route through the interpolation. This can be set to any valid ease string, such as sine.out or quad.in, etc. If left undefined it will use linear as default.
  • EmitterColorOp is a brand new Emitter Op class that specifically controls the handling of color values, it extends EmitterOp and uses the same methods but configured for faster color interpolation.
  • If you define color in your config it will override any Emitter tint values you may have set. In short, use color if you wish to adjust the color of the particles during their lifespan and use tint if you wish to modify either the entire emitter at once, or the color of the particles on birth only.
  • ParticleEmitter.particleColor is a new property that allows you to get and set the particle color op value.
  • ParticleEmitter.colorEase is a new property that allows you to get and set the ease function used by the color op.

Particle Sort Order

  • You now have much more control over the sorting order of particles in an Emitter. You can set the new ParticleEmitter.sortProperty and sortOrderAsc properties to set how (and if) particles should be sorted prior to rendering. For example, setting sortProperty to y would mean that the particles will be sorted based on their y value prior to rendering. The sort order controls the order in which the particles are rendered. For example:

```js const emitter = this.add.particles(100, 300, 'blocks', { frame: 'redmonster', lifespan: 5000, angle: { min: -30, max: 30 }, speed: 150, frequency: 200 });

emitter.setSortProperty('y', true); ```

  • The new ParticleEmitter.setSortProperty method allows you to modify the sort property and order at run-time.
  • The new ParticleEmitter.setSortCallback method allows you to set a callback that will be invoked in order to sort the particles, rather than using the built-in one. This gives you complete freedom over the logic applied to particle render sorting.

Particle Bounds, Renderer Culling and Overlap

  • Particles now have the ability to calculate their bounding box, based on their position, scale, rotation, texture frame and the transform of their parent. You can call the new Particle.getBounds method to return the bounds, which also gets stored in the new Particle.bounds Rectangle property.
  • ParticleEmitter.getBounds is a new method that will return the bounds of the Emitter based on all currently active particles. Optional parameters allow you to pad out the bounds and/or advance time in the particle flow, to allow for a more accurate overall bounds generation.
  • ParticleEmitter.viewBounds is a new property that is a Geom Rectangle. Set this Rectangle to define the overall area the emitter will render to. If this area doesn't intersect with the Camera then the emitter will be culled from rendering. This allows you to populate large Scenes with active emitters that don't consume rendering resources even though they are offscreen. Use the new getBounds method to help define the viewBounds area.
  • ParticleEmitter.overlap is a new method that will run a rectangle intersection test against the given target and all alive particles, returning those that overlap in an array. The target can be a Rectangle Geometry object or an Arcade Physics Body.
  • Particle.kill is a new method that will set the life of the particle to zero, forcing it to be immediately killed on the next Particle Emitter update.
  • ParticleEmitter.getWorldTransformMatrix is a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.
  • ParticleEmitter.worldMatrix is a new property that holds a TransformMatrix used for bounds calculations.

Particle Emitter Bounds

  • Prior to v3.60 a Particle Emitter had a bounds property. This was a Rectangle and if a Particle hit any of its edges it would rebound off it based on the Particles bounce value. In v3.60 this action has been moved to a Particle Processor. You can still configure the bounds via the Emitter config using the bounds property, as before. And you can configure which faces collide via the collideLeft etc properties. However, the following internal changes have taken place:
  • ParticleBounds is a new Particle Processor class that handles updating the particles.
  • The ParticleEmitter.setBounds method has been replaced with ParticleEmitter.addParticleBounds which now returns a new ParticleBounds Particle Processor instance.
  • The ParticleEmitter.bounds property has been removed. Please see the addParticleBounds method if you wish to retain this object.
  • The ParticleEmitter.collideLeft property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideRight property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideTop property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideBottom property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The Particle.checkBounds method has been removed as it's now handled by the Particle Processors.

Particle Processors

  • ParticleProcessor is a new base class that you can use to create your own Particle Processors, which are special processors capable of manipulating the path of Particles based on your own logic or math. It provides the structure required to handle the processing of particles and should be used as a base for your own classes.
  • GravityWell now extends the new ParticleProcessor class.
  • ParticleEmitter.addParticleProcessor is a new method that allows you to add a Particle Processor instance to the Emitter. The old createGravityWell method now uses this.
  • ParticleEmitter.removeParticleProcessor is a new method that will remove a Particle Processor from an Emitter.
  • ParticleEmitter.processors is a new List property that contains all of the Particle Processors belonging to the Emitter.
  • The ParticleEmitter.wells property has been removed. You should now use the new processors property instead, they are functionally identical.
  • ParticleProcessor.update is the method that handles all of the particle manipulation. It now has a new 4th parameter t that is the normalized lifespan of the Particle being processed.

Particle System EmitterOp Breaking Changes and Updates:

All of the following properties have been replaced on the ParticleEmitter class. Previously they were EmitterOp instances. They are now public getter / setters, so calling, for example, emitter.particleX will now return a numeric value - whereas before it would return the EmitterOp instance. This gives developers a lot more freedom when using Particle Emitters. Before v3.60 it was impossible to do this, for example:

js this.tweens.add({ targets: emitter, particleX: 400 });

I.e. you couldn't tween an emitters particle spawn position by directly accessing its x and y properties. However, now that all EmitterOps are getters, you're free to do this, allowing you to be much more creative and giving a nice quality-of-life improvement.

If, however, your code used to access EmitterOps, you'll need to change it as follows:

```js // Phaser 3.55 emitter.x.onChange(value) // Phaser 3.60 emitter.particleX = value

// Phaser 3.55 let x = emitter.x.propertyValue // Phaser 3.60 let x = emitter.particleX

// Phaser 3.55 emitter.x.onEmit() emitter.x.onUpdate() // Phaser 3.60 emitter.ops.x.onEmit() emitter.ops.x.onUpdate() ```

All of following EmitterOp functions can now be found in the new ParticleEmitter.ops property and have been replaced with getters:

  • accelerationX
  • accelerationY
  • alpha
  • angle
  • bounce
  • color
  • delay
  • lifespan
  • maxVelocityX
  • maxVelocityY
  • moveToX
  • moveToY
  • quantity
  • rotate
  • scaleX
  • scaleY
  • speedX
  • speedY
  • tint
  • x
  • y

Which means you can now directly access, modify and tween any of the above emitter properties at run-time while the emitter is active.

Another potentially breaking change is the removal of two internal private counters. These should never have been used directly anyway, but they are:

  • ParticleEmitter._counter - Now available via ParticleEmitter.flowCounter
  • ParticleEmitter._frameCounter - Now available via ParticleEmitter.frameCounter
  • EmitterOp._onEmit is a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyEmit method, to ensure that the Emitter current property remains current.
  • EmitterOp._onUpdate is a new private reference to the update callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyUpdate method, to ensure that the Emitter current property remains current.
  • EmitterOp.destroy is a new method that nulls all references. This is called automatically when a ParticleEmitter is itself destroyed.

Further Particle System Updates and Fixes:

  • The Particle DeathZone.willKill method now takes a Particle instance as its only parameter, instead of x and y coordinates, allowing you to perform more complex checks before deciding if the Particle should be killed, or not.
  • The Particle.resetPosition method has been renamed to setPosition and it now takes optional x/y parameters. If not given, it performs the same task as resetPosition did in earlier versions.
  • The ParticleEmitter class now has the AlphaSingle Component. This allows you to call setAlpha on the Emitter instance itself and have it impact all particles being rendered by it, allowing you to now 'fade in/out' a whole Emitter.
  • Setting frequency wasn't working correctly in earlier versions. It should allow you to specify a time, in ms, between which each 'quantity' of particles is emitted. However, the preUpdate loop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles.
  • Calling ParticleEmitter.start wouldn't reset the _frameCounter value internally, meaning the new emission didn't restart from the first texture frame again.
  • ParticleEmitter.counters is a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous _counter and _frameCounter properties have been merged into this array, along with new ones required for new features.
  • The WebGL Renderer will now use the new setQuad feature of the Transform Matrix. This vastly reduces the amount of math and function calls per particle, from 8 down to 1, increasing performance.
  • Particles with a scaleX or scaleY value of zero will no longer be rendered.
  • ParticleEmitter.preDestroy is a new method that will now clean-up all resources and internal arrays and destroy all Particles that the Emitter owns and clean-up all external references.
  • Particle.destroy is a new method that will clean up all external references and destroy the Animation State controller.
  • The ParticleEmitter._frameLength property is now specified on the class, rather than added dynamically at run-time, helping preserve class shape.
  • The ParticleEmitter.defaultFrame property has been removed as it's not required.
  • Calling ParticleEmitter.setFrame no longer resets the internal _frameCounter value to zero. Instead, the counter comparison has been hardened to >= instead of === to allow this value to change mid-emission and never reach the total.
  • The ParticleEmitter.configFastMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • The ParticleEmitter.configOpMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • Particle.scene is a new property that references the Scene the Particle Emitter belongs to.
  • Particle.anims is a new property that is an instance of the AnimationState component.
  • Particle.emit is a new proxy method that passes all Animation related events through to the Particle Emitter Manager to emit, as Particles cannot emit events directly.
  • Particle.isCropped is a new read-only property. Do not modify.
  • Particle.setSizeToFrame is a new internal NOOP method. Do not call.
  • ParticleEmitter.anims is a new property that contains the Animation keys that can be assigned to Particles.
  • ParticleEmitter.currentAnim is a new property that contains the index of the current animation, as tracked in cycle playback.
  • ParticleEmitter.randomAnim is a new boolean property that controls if the animations are selected randomly, or in a cycle.
  • ParticleEmitter.animQuantity is a new property that controls the number of consecutive particles that are emitted with the current animation.
  • ParticleEmitter.counters is a new internal Float32Array that holds all the counters the Emitter uses.
  • ParticleEmitter.getAnim is a new method, called by Particles when they are emitted, that will return the animation to use, if any.
  • ParticleEmitter.setAnim is a new method, called with the Emitter Manager, that sets the animation data into the Emitter.
  • The Particles.EmitterOp.toJSON method will now JSON stringify the property value before returning it.
  • Particles.EmitterOp.method is a new property that holds the current operation method being used. This is a read-only numeric value.
  • Particles.EmitterOp.active is a new boolean property that defines if the operator is alive, or not. This is now used by the Emitter instead of nulling Emitter properties, helping maintain class shape.
  • Particles.EmitterOp.getMethod is a new internal method that returns the operation function being used as a numeric value. This is then cached in the method property.
  • The Particles.EmitterOp.setMethods method has been updated so it now has a non-optional 'method' parameter. It has also been rewritten to be much more efficient, now being just a single simple select/case block.
  • The Particles.EmitterOp.onChange method will now use the cached 'method' property to avoid running through the setMethods function if not required, allowing each Particle EmitterOp to skip a huge chunk of code.
  • We've also greatly improved the documentation around the Particle classes.
  • ParticleEmitter.setConfig is a new method that allows you to set the configuration of the Emitter. Previously this was known as fromJSON.
  • The ParticleEmitter.setPosition method no longer changes the position of the particle emission point, but of the Emitter itself.
  • The ParticleEmitter.setBounds method has been renamed to setParticleBounds.
  • The ParticleEmitter.setSpeed method has been renamed to setParticleSpeed.
  • The ParticleEmitter.setScale method has been renamed to setParticleScale as setScale will now set the scale of the whole Emitter.
  • The ParticleEmitter.setScaleX and setScaleY methods have been removed. Please use setParticleScale.
  • The ParticleEmitter.setGravity method has been renamed to setParticleGravity.
  • The ParticleEmitter.setGravityX and setGravityY methods have been removed. Please use setParticleGravity.
  • The ParticleEmitter.setAlpha method has been renamed to setParticleAlpha as setAlpha will now set the alpha of the whole Emitter.
  • The ParticleEmitter.setTint method has been renamed to setParticleTint.
  • The ParticleEmitter.setLifespan method has been renamed to setParticleLifespan.
  • The ParticleEmitter.on property has been renamed to emitting to avoid conflicts with the Event Emitter.
  • The ParticleEmitter.x property has been renamed to particleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.y property has been renamed to particleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleX property has been renamed to particleScaleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleY property has been renamed to particleScaleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.tint property has been renamed to particleTint and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.alpha property has been renamed to particleAlpha and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.angle property has been renamed to particleAngle and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.rotate property has been renamed to particleRotate and is a new EmitterOp capable of being tweened.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

TODO

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

  • The RenderTarget class will now create a Framebuffer that includes a Depth Stencil Buffer attachment by default. Previously, it didn't. By attaching a stencil buffer it allows things like Geometry Masks to work in combination with Post FX and other Pipelines. Fix #5802 (thanks @mijinc0)
  • When calling PipelineManager.clear and rebind it will now check if the vao extension is available, and if so, it'll bind a null vertex array. This helps clean-up from 3rd party libs that don't do this directly, such as ThreeJS.
  • The mipmapFilter property in the Game Config now defaults to '' (an empty string) instead of 'LINEAR'. The WebGLRenderer has been updated so that it will no longer create mipmaps at all with a default config. This potential saves a lot of VRAM (if your game has a lot of power-of-two textures) where before it was creating mipmaps that may never have been used. However, you may notice scaling doesn't look as crisp as it did before if you were using this feature without knowing it. To get it back, just add mipmapFilter: 'LINEAR' to your game config. Remember, as this is WebGL1 it only works with power-of-two sized textures.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • The batchLine method in the Multi Pipeline will now check to see if the dxdy len is zero, and if so, it will abort drawing the line. This fixes issues on older Android devices, such as the Samsung Galaxy S6 or Kindle 7, where it would draw erroneous lines leading up to the top-left of the canvas under WebGL when rendering a stroked rounded rectangle. Fix #5429 (thanks @fkoch-tgm @sreadixl)
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light fragment shader will now use the outTintEffect attribute meaning the Light Pipeline will now correctly light both tinted and fill-tinted Game Objects. Fix #5452 (thanks @kainage)
  • The Light Pipeline will now check to see if a Light2D enabled Game Object has a parent Container, or not, and factor the rotation and scale of this into the light calculation. Fix #6086 (thanks @irongaze)
  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been rewritten to help with performance, resolve some of its lingering issues and unifies the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • The Tween.seek method used to take a value between 0 and 1, based on how far through the Tween you wished to seek. However, it did not work with infinitely looping or repeating Tweens and would crash the browser tab. The new seek method takes a value in milliseconds instead and works perfectly on infinite Tweens.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as the source for a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • origin is now (0.5, 0.5) by default instead of (0, 0).

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Post Pipeline Updates

In order to add clarity in the codebase we have created a new PostPipeline Component and moved all of the relevant functions from the Pipeline component in to it. This leads to the following changes:

  • PostPipeline is a new Game Object Component that is now inherited by all Game Objects that are capable of using it.
  • Game Objects with the PostPipeline component now have a new property called postPipelineData. This object is used for storing Post Pipeline specific data in. Previously, both regular and post pipelines used the same pipelineData object, but this has now been split up for flexibility.
  • The Pipeline.resetPipeline method no longer has its first resetPostPipelines argument. It now has just one argument resetData so please be aware of this if you call this function anywhere in your code.
  • PostPipeline.initPostPipeline is a new method that should be called by any Game Object that supports Post Pipelines.
  • The following Game Objects now have the new PostPipeline Component exclusively: Container and Layer.

Input System Updates

There are breaking changes from previous versions of Phaser.

  • The InteractiveObject.alwaysEnabled property has been removed. It is no longer checked within the InputPlugin and setting it will have no effect. This property has not worked correctly since version 3.52 when the new render list was implemented. Upon further investigation we decided to remove the property entirely, rather than shoe-horn it into the render list. If you need to create a non-rendering Interactive area, use the Zone Game Object instead.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.
  • The GameObjects.Components.Mask.createBitmapMask method can now accept the x, y, texture and frame parameters new to the BitmapMask constructor.
  • Previously, calling createBitmapMask on a Shape Game Object would fail unless you passed the shape to the method. Now, it will correctly create a mask from the Shape without needing to pass it. Fix #5976 (thanks @samme)

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • The Hexagonal Tilemap system now supports all 4 different types of layout as offered by Tiled: staggeraxis-y + staggerindex-odd, staggeraxis-x + staggerindex-odd, staggeraxis-y + staggerindex-even and staggeraxis-x, staggerindex-even (thanks @rexrainbow)
  • The Arcade Physics World has a new property tileFilterOptions which is an object passed to the GetTilesWithin methods used by the Sprite vs. Tilemap collision functions. These filters dramatically reduce the quantity of tiles being checked for collision, potentially saving thousands of redundant math comparisons from taking place.
  • The Graphics.strokeRoundedRect and fillRoundedRect methods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow)
  • AnimationManager.getAnimsFromTexture is a new method that will return all global Animations, as stored in the Animation Manager, that have at least one frame using the given Texture. This will not include animations created directly on local Sprites.
  • BitmapText.setLineSpacing is a new method that allows you to set the vertical spacing between lines in multi-line BitmapText Game Objects. It works in the same was as spacing for Text objects and the spacing value can be positive or negative. See also BitmapText.lineSpacing for the property rather than the method.
  • WebGLPipeline.vertexAvailable is a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.
  • The Tilemap and TilemapLayer classes have a new method getTileCorners. This method will return an array of Vector2s with each entry corresponding to the corners of the requested tile, in world space. This currently works for Orthographic and Hexagonal tilemaps.
  • BaseSoundManager.getAllPlaying is a new method that will return all currently playing sounds in the Sound Manager.
  • Animation.showBeforeDelay is a new optional boolean property you can set when creating, or playing an animation. If the animation has a delay before playback starts this controls if it should still set the first frame immediately, or after the delay has expired (the default).
  • InputPlugin.resetPointers is a new method that will loop through all of the Input Manager Pointer instances and reset them all. This is useful if a 3rd party component, such as Vue, has stolen input from Phaser and you need to reset its input state again.
  • Pointer.reset is a new method that will reset a Pointer instance back to its 'factory' settings.
  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • Game.isPaused is a new boolean that tracks if the Game loop is paused, or not (and can also be toggled directly)
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • You will now get a warning from the AnimationManager and AnimationState if you try to add an animation with a key that already exists. Fix #6434.
  • Tilemap.addTilesetImage has a new optional parameter tileOffset which, if given, controls the rendering offset of the tiles. This was always available on the Tileset itself, but not from this function (thanks @imothee)
  • The GameObject.getBounds method will now return a Geom.Rectangle instance, rather than a plain Object (thanks @samme)
  • The GetBounds.getCenter method now has an optional includeParent argument, which allows you to get the value in world space.
  • The MatterTileBody class, which is created when you convert a Tilemap into a Matter Physics world, will now check to see if the Tile has flipX or flipY set on it and rotate the body accordingly. Fix #5893 (thanks @Olliebrown @phaserhelp)
  • The BaseCamera has had its Alpha component replaced with AlphaSingle. Previously you had access to properties such as alphaTopLeft that never worked, now it correctly has just a single alpha property (thanks @samme)
  • Time.Clock.startTime is a new property that stores the time the Clock (and therefore the Scene) was started. This can be useful for comparing against the current time to see how much real world time has elapsed (thanks @samme)
  • ColorMatrix._matrix and _data are now Float32Arrays.
  • Calling the ColorMatrix.set, reset and getData methods all now use the built-in Float32 Array operations, making them considerably faster.
  • ColorMatrix.BLACK_WHITE is a new constant used by blackwhite operations.
  • ColorMatrix.NEGATIVE is a new constant used by negative operations.
  • ColorMatrix.DESATURATE_LUMINANCE is a new constant used by desaturation operations.
  • ColorMatrix.SEPIA is a new constant used by sepia operations.
  • ColorMatrix.LSD is a new constant used by LSD operations.
  • ColorMatrix.BROWN is a new constant used by brown operations.
  • ColorMatrix.VINTAGE is a new constant used by vintage pinhole operations.
  • ColorMatrix.KODACHROME is a new constant used by kodachrome operations.
  • ColorMatrix.TECHNICOLOR is a new constant used by technicolor operations.
  • ColorMatrix.POLAROID is a new constant used by polaroid operations.
  • ColorMatrix.SHIFT_BGR is a new constant used by shift BGR operations.
  • If no Audio URLs match the given device a new warning is now displayed in the console (thanks @samme)
  • Texture.has will now return a strict boolean, rather than an object that can be cooerced into a boolean (thanks @samme)
  • The CanvasTexture.draw method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The CanvasTexture.drawFrame method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The CanvasTexture.clear method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The Game.registry, which is a DataManager instance that can be used as a global store of game wide data will now use its own Event Emitter, instead of the Game's Event Emitter. This means it's perfectly safe for you to now use the Registry to emit and listen for your own custom events without conflicting with events the Phaser Game instance emits.
  • The GenerateVerts function has a new optional parameter flipUV which, if set, will flip the UV texture coordinates (thanks cedarcantab)
  • The GenerateVerts function no longer errors if the verts and uvs arrays are not the same size and containsZ is true (thanks cedarcantab)
  • The Device.Browser checks for Opera and Edge have been updated to use the more modern user agent strings those browsers now use. This breaks compatibility with really old versions of those browsers but fixes it for modern ones (which is more important) (thanks @ ArtemSiz)
  • The SceneManager.processQueue method will no longer return if a new Scene was added, after starting it. This allows any other queued operations to still be run in the same frame, rather than being delayed until the next game frame. Fix #5359 (thanks @telinc1)
  • Camera.scrollX and scrollY will now only set the Camera.dirty flag to true if the new value given to them is different from their current value. This allows you to use this property in your own culling functions. Fix #6088 (thanks @Waclaw-I)
  • Face.update is a new method that updates each of the Face vertices. This is now called internally by Face.isInView.
  • Vertex.resize is a new method that will set the position and then translate the Vertex based on an identity matrix.
  • The Vertex.update method now returns this to allow it to be chained.
  • You can now optionally specify the maxSpeed value in the Arcade Physics Group config (thanks @samme)
  • You can now optionally specify the useDamping boolean in the Arcade Physics Group config (thanks @samme)
  • Removed the HexagonalTileToWorldY function as it cannot work without an X coordinate. Use HexagonalTileToWorldXY instead.
  • Removed the HexagonalWorldToTileY function as it cannot work without an X coordinate. Use HexagonalWorldToTileXY instead.
  • Earcut has been updated to version 2.2.4. This release improves performance by 10-15% and fixes 2 rare race conditions that could leave to infinite loops. Earcut is used internally by Graphics and Shape game objects when triangulating polygons for complex shapes.
  • The BaseSoundManager.getAll method used to require a key parameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned.
  • The WebAudioSoundManager will now detect if the Audio Context enters a 'suspended' or 'interrupted' state as part of its update loop and if so it'll try to resume the context. This can happen if you change or disable the audio device, such as plugging in headphones with built-in audio drivers then disconnecting them, or swapping tabs on iOS. Fix #5353 (thanks @helloyoucan)
  • The CONTEXT_RESTORED Game Event has been removed and the WebGL Renderer no longer listens for the contextrestored DOM event, or has a contextRestoredHandler method. This never actually worked properly, in any version of Phaser 3 - although the WebGLRenderer would be restored, none of the shaders, pipelines or textures were correctly re-created. If a context is now lost, Phaser will display an error in the console and all rendering will halt. It will no longer try to re-create the context, leading to masses of WebGL errors in the console. Instead, it will die gracefully and require a page reload.
  • The Text and TileSprite Game Objects no longer listen for the CONTEXT_RESTORED event and have had their onContextRestored methods removed.
  • Scenes.Systems.canInput is a new internal method that determines if a Scene can receive Input events, or not. This is now used by the InputPlugin instead of the previous isActive test. This allows a Scene to emit and handle input events even when it is running init or preload. Previously, it could only do this after create had finished running. Fix #6123 (thanks @yaasinhamidi)
  • The BitmapText Game Object has two new read-only properties displayWidth and displayHeight. This allows the BitmapText to correctly use the GetBounds component.
  • The BitmapText Game Object now has the GetBounds component added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames)
  • WebGLSnapshot will now flip the pixels in the created Image element if the source was a framebuffer. This means grabbing a snapshot from a Dynamic or Render Texture will now correctly invert the pixels on the y axis for an Image. Grabbing from the game renderer will skip this.
  • WebGLRenderer.snapshotFramebuffer and by extension, the snapshot methods in Dynamic Textures and Render Textures, has been updated to ensure that the width and height never exceed the framebuffer dimensions, or it'll cause a runtime error. The method snapshotArea has had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)
  • Animation.stop is always called when a new animation is loaded, regardless if the animation was playing or not and the delayCounter is reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)
  • ScaleManager.listeners has been renamed to domlisteners to avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)
  • Geom.Intersects.LineToLine will no longer create an internal Point object, as it's not required internally (thanks @Trissolo)
  • The tempZone used by GridAlign has now had setOrigin(0, 0) applied to it. This leads to more accurate / expected zone placement when aligning grid items.
  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • The TilemapLayer.skipCull feature wasn't being applied correctly for Isometric, Hexagonal or Staggered tiles, only for Orthographic tiles (the default). It will now respect the skipCull property and return all tiles during culling if enabled. Fix #5524 (thanks @veleek)
  • Shutting down a Scene that didn't have the LoaderPlugin would throw an error when removing event handlers. It now checks first, before removing (thanks @samme)
  • The Container.getBounds method will now use getTextBounds if one of its children is a BitmapText Game Object, giving more accurate bounds results (thanks @EmilSV)
  • The renderFlags property, used to determine if a Game Object will render, or not, would be calculated incorrectly depending on the order of the scaleX and scaleY properties. It now works regardless of the order (thanks @mizunokazumi)
  • The SpriteSheetFromAtlas parser was using the incorrect sourceIndex to grab frames from a given texture. This caused a crash whenever a trimmed spritesheet was added from any multiatlas image other than the first (thanks @Bambosh)
  • The maxSpeed setting in Arcade Physics wasn't recalculated during the Body update, prior to being compared, leading to inconsistent results. Fix #6329 (thanks @Bambosh)
  • Several paths have been fixed in the phaser-core.js entry point (thanks @pavle-goloskokovic)
  • When a Game Object had Input Debug Enabled the debug image would be incorrectly offset if the Game Object was attached to was scaled and the hit area shape was smaller, or offset, from the Game Object. Fix #4905 #6317 (thanks @PavelMishin @justinlueders)
  • An inactive Scene is no longer updated after a Scene transition completes. Previously, it will still update the Scene one final time. This fix also prevents the POST_UPDATE event from firing after the transition is over. Fix #5550 (thanks @mijinc0 @samme)
  • Although not recommended, when adding a Layer Game Object to another Layer Game Object, it will no longer error because it cannot find the removeFromDisplayList function. Fix #5595 (thanks @tringcooler)
  • The Actions.Spread method will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV)
  • Calling setDisplayOrigin on a Video Game Object would cause the origins to be set to NaN if the Video was created without an asset key. It will now give Videos a default size, preventing this error, which is reset once a video is loaded. Fix #5560 (thanks @mattjennings)
  • When ImageFile loads with a linked Normal Map and the map completes first, but the Image is still in a pending state, it would incorrectly add itself to the cache instead of waiting. It now checks this process more carefully. Fix #5886 (thanks @inmylo)
  • Using a dataKey to specify a part of a JSON file when using load.pack would fail as it wouldn't correctly assign the right part of the pack file to the Loader. You can now use this parameter properly. Fix #6001 (thanks @rexrainbow)
  • The Text.advancedWordWrap function would incorrectly merge the current and next lines when wrapping words with carriage-returns in. Fix #6187 (thanks @Ariorh1337 @robinheidrich)
  • Recoded the point conversion math in the HexagonalTileToWorldXY function as it was incorrect. Now returns world coordinates correctly.
  • Tilemap.copy would error if you copied a block of tiles over itself, even partially, as it tried to copy already replaced tiles as part of the function. It will now copy correctly, regardless of source or destination areas. Fix #6188 (thanks @Arkyris)
  • Tile.copy will now use the DeepCopy function to copy the Tile.properties object, as otherwise it just gets copied by reference.
  • Recoded the point conversion math in the HexagonalWorldToTileXY function as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich)
  • Fixed the point conversion math in the IsometricWorldToTileXY function and added optional boolean property that allows the setting of the tile origin to the top or base. Fix #5781 (thanks @benjamin-wilson)
  • Calling Tilemap.worldToTileX or worldToTileY on a Isometric or Hexagonal Tilemap will now always return null instead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should use worldToTileXY instead.
  • The Game.headlessStep method will now reset SceneManager.isProcessing before PRE_RENDER. This fixes issues in HEADLESS mode where the Scene Manager wouldn't process additionally added Scenes created after the Game had started. Fix #5872 #5974 (thanks @micsun-al @samme)
  • If Rope.setPoints was called with the exact same number of points as before, it wouldn't set the dirty flag, meaning the vertices were not updated on the next render (thanks @stupot)
  • Particle.fire will now check to see if the parent Emitter is set to follow a Game Object and if so, and if the x/y EmitterOps are spread ops, then it'll space the particles out based on the follower coordinates, instead of clumping them all together. Fix #5847 (thanks @sreadixl)
  • When using RTL (right-to-left) Text Game Objects, the Text would vanish on iOS15+ if you changed the text or font style. The context RTL properties are now restored when the text is updated, fixing this issue. Fix #6121 (thanks @liorGameDev)
  • The Tilemap.destroyLayer method would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme)
  • MapData and ObjectLayer will now enforce that the Tilemap.objects property is always an array. Sometimes Tiled willl set it to be a blank object in the JSON data. This fix makes sure it is always an array. Fix #6139 (thanks @robbeman)
  • The ParseJSONTiled function will now run a DeepCopy on the source Tiled JSON, which prevents obje

- JavaScript
Published by photonstorm about 3 years ago

phaser - Phaser 3.60.0 Beta 21

Version 3.60.0 - Miku - in development

New Features - ESM Support

Phaser 3.60 uses the new release of Webpack 5 in order to handle the builds. The configurations have been updated to follow the new format this upgrade introduced. As a bonus, Webpack 5 also bought a new experimental feature called 'output modules', which will take a CommonJS code-base, like Phaser uses and wrap the output in modern ES Module declarations.

We are now using this as part of our build. You will find in the dist folder a new phaser.esm.js file, which is also linked in from our package.json module property. Using this build you can access any of the Phaser modules directly via named imports, meaning you can code like this:

```js import { AUTO, Scene, Game } from './phaser.esm.js';

class Test extends Scene { constructor () { super(); }

create ()
{
    this.add.text(10, 10, 'Welcome to Phaser ESM');
}

}

const config = { type: AUTO, width: 800, height: 600, parent: 'phaser-example', scene: [ Test ] };

const game = new Game(config); ```

Note that we're importing from the local esm bundle. By using this approach you don't need to even use a bundler for quick local prototyping or testing, you can simply import and code directly.

The dist folder still also contains phaser.js which, as before, uses a UMD export.

Because the Webpack feature is experimental we won't make the ESM version the default just yet, but if you're curious and want to explore, please go ahead!

New Features - Built-in Special FX

We have decided to bundle a selection of highly flexible special effect shaders in to Phaser 3.60 and provide access to them via an easy to use set of API calls. The FX included are:

  • Barrel - A nice pinch / bulge distortion effect.
  • Bloom - Add bloom to any Game Object, with custom offset, blur strength, steps and color.
  • Blur - 3 different levels of gaussian blur (low, medium and high) and custom distance and color.
  • Bokeh / TiltShift - A bokeh and tiltshift effect, with intensity, contrast and distance settings.
  • Circle - Add a circular ring around any Game Object, useful for masking / avatar frames, with custom color, width and background color.
  • ColorMatrix - Add a ColorMatrix to any Game Object with access to all of its methods, such as sepia, greyscale, lsd and lots more.
  • Displacement - Use a displacement texture, such as a noise texture, to drastically (or subtly!) alter the appearance of a Game Object.
  • Glow - Add a smooth inner or outer glow, with custom distance, strength and color.
  • Gradient - Draw a gradient between two colors across any Game Object, with optional 'chunky' mode for classic retro style games.
  • Pixelate - Make any Game Object appear pixelated, to a varying degree.
  • Shadow - Add a drop shadow behind a Game Object, with custom depth and color.
  • Shine - Run a 'shine' effect across a Game Object, either additively or as part of a reveal.
  • Vignette - Apply a vignette around a Game Object, with custom offset position, radius and color.
  • Wipe - Set a Game Object to 'wipe' or 'reveal' with custom line width, direction and axis of the effect.

What's more, the FX can be stacked up. You could add, for example, a Barrel followed by a Blur and then topped-off with a Circle effect. Just by adjusting the ordering you can achieve some incredible and unique effects, very quickly.

We've worked hard to make the API as easy to use as possible, too. No more messing with pipelines or importing plugins. You can simply do:

```js const player = this.add.sprite(x, y, texture);

player.preFX.addGlow(0xff0000, 32); ```

This will add a 32 pixel red glow around the player Sprite.

Each effect returns a new FX Controller instance, allowing you to easily adjust the special effects in real-time via your own code, tweens and similar:

```js const fx = container.postFX.addWipe();

this.tweens.add({ targets: fx, progress: 1 }); ```

This will add a Wipe Effect to a Container instance and then tween its progress value from 0 to 1, causing the wipe to play out.

All texture-based Game Objects have access to Pre FX (so that includes Images, Sprites, TileSprites, Text, RenderTexture and Video). However, all Game Objects have access to Post FX, as do cameras. The difference is just when the effect is applied. For a 'pre' effect, it is applied before the Game Object is drawn. For a 'post' effect, it's applied after it has been drawn. All of the same effects are available to both.

js this.cameras.main.postFX.addTiltShift();

For example, this will apply a Tilt Shift effect to everything being rendered by the Camera. Which is a much faster way of doing it than applying the same effect to every child in a Scene. You can also apply them to Containers, allowing more fine-grained control over the display.

The full list of new methods are as follows:

Available only to texture-based Game Objects:

  • GameObject.preFX.addGlow adds a Glow Pre FX effect to the Game Object.
  • GameObject.preFX.addShadow adds a Shadow Pre FX effect to the Game Object.
  • GameObject.preFX.addPixelate adds a Pixelate Pre FX effect to the Game Object.
  • GameObject.preFX.addVignette adds a Vignette Pre FX effect to the Game Object.
  • GameObject.preFX.addShine adds a Shine Pre FX effect to the Game Object.
  • GameObject.preFX.addBlur adds a Blur Pre FX effect to the Game Object.
  • GameObject.preFX.addGradient adds a Gradient Pre FX effect to the Game Object.
  • GameObject.preFX.addBloom adds a Bloom Pre FX effect to the Game Object.
  • GameObject.preFX.addColorMatrix adds a ColorMatrix Pre FX effect to the Game Object.
  • GameObject.preFX.addCircle adds a Circle Pre FX effect to the Game Object.
  • GameObject.preFX.addBarrel adds a Barrel Pre FX effect to the Game Object.
  • GameObject.preFX.addDisplacement adds a Displacement Pre FX effect to the Game Object.
  • GameObject.preFX.addWipe adds a Wipe Pre FX effect to the Game Object.
  • GameObject.preFX.addReveal adds a Reveal Pre FX effect to the Game Object.
  • GameObject.preFX.addBokeh adds a Bokeh Pre FX effect to the Game Object.
  • GameObject.preFX.addTiltShift adds a TiltShift Pre FX effect to the Game Object.

Available to all Game Objects:

  • GameObject.postFX.addGlow adds a Glow Post FX effect to the Game Object.
  • GameObject.postFX.addShadow adds a Shadow Post FX effect to the Game Object.
  • GameObject.postFX.addPixelate adds a Pixelate Post FX effect to the Game Object.
  • GameObject.postFX.addVignette adds a Vignette Post FX effect to the Game Object.
  • GameObject.postFX.addShine adds a Shine Post FX effect to the Game Object.
  • GameObject.postFX.addBlur adds a Blur Post FX effect to the Game Object.
  • GameObject.postFX.addGradient adds a Gradient Post FX effect to the Game Object.
  • GameObject.postFX.addBloom adds a Bloom Post FX effect to the Game Object.
  • GameObject.postFX.addColorMatrix adds a ColorMatrix Post FX effect to the Game Object.
  • GameObject.postFX.addCircle adds a Circle Post FX effect to the Game Object.
  • GameObject.postFX.addBarrel adds a Barrel Post FX effect to the Game Object.
  • GameObject.postFX.addDisplacement adds a Displacement Post FX effect to the Game Object.
  • GameObject.postFX.addWipe adds a Wipe Post FX effect to the Game Object.
  • GameObject.postFX.addReveal adds a Reveal Post FX effect to the Game Object.
  • GameObject.postFX.addBokeh adds a Bokeh Post FX effect to the Game Object.
  • GameObject.postFX.addTiltShift adds a TiltShift Post FX effect to the Game Object.

New Features - Spatial Sound

Thanks to a contribution from @alxwest the Web Audio Sound system now supports spatial sound.

TODO - List all of the new properties and methods!

New Features - Spine 4 Support

Thanks to a contribution from @justintien we now have a Spine 4 Plugin available.

You can find it in the plugins/spine4.1 folder in the main repository. There are also a bunch of new npm scripts to help build this plugin:

npm run plugin.spine4.1.full.dist - To build new dist files for both canvas and WebGL. npm run plugin.spine4.1.dist - To build new dist files. npm run plugin.spine4.1.watch - To enter watch mode when doing dev work on the plugin. npm run plugin.spine4.1.runtimes - To build new versions of the Spine 4 runtimes.

The core plugin API remains largely the same. You can find lots of updated examples in the Phaser 3 Examples repo in the 3.60/spine4.1 folder.

We will maintain both the Spine 3 and 4 plugins for the forseeable future.

Additional Spine 3 Bug Fixes

  • Using drawDebug on a Spine Game Object to view its skeleton would cause the next object in the display list to be skipped for rendering, if it wasn't a Spine Game Object too. This is because the Spine 3 skeleton debug draw ends the spine batch but the Scene Renderer wasn't rebound. Fix #6380 (thanks @spayton)
  • The Spine Plugin add and make functions didn't clear and rebind the WebGL pipeline. This could cause two different visual issues: The first is that a Phaser Game Object (such as a Sprite) could be seen to change its texture to display the Spine atlas texture instead for a single frame, and then on the next pass revert back to normal again. The second issue is that if the Spine skeleton wasn't added to the display list, but just created (via addToScene: false) then the Sprite would take on the texture frame entirely from that point on. Fix #6362 (thanks @frissonlabs)
  • Previously, it wasn't possible for multiple Spine Atlases to use PNGs with the exact same filename, even if they were in different folders. The SpineFile loader has now been updated so that the always-unique Spine key is pre-pended to the filename, for example if the key was bonus and the PNG in the atlas was coin.png then the final key (as stored in the Texture Manager) is now bonus:coin.png. The SpinePlugin.getAtlasCanvas and getAtlasWebGL methods have been updated to reflect this change. Fix #6022 (thanks @orjandh)
  • If a SpineContainer had a mask applied to it and the next immediate item on the display list was another Spine object (outside of the Container) then it would fail to rebind the WebGL pipeline, causing the mask to break. It will now rebind the renderer at the end of the SpineContainer batch, no matter what, if it has a mask. Fix #5627 (thanks @FloodGames)

New Features - Plane Game Object

Phaser v3.60 contains a new native Plane Game Object. The Plane Game Object is a helper class that takes the Mesh Game Object and extends it, allowing for fast and easy creation of Planes. A Plane is a one-sided grid of cells, where you specify the number of cells in each dimension. The Plane can have a texture that is either repeated (tiled) across each cell, or applied to the full Plane.

The Plane can then be manipulated in 3D space, with rotation across all 3 axis.

This allows you to create effects not possible with regular Sprites, such as perspective distortion. You can also adjust the vertices on a per-vertex basis. Plane data becomes part of the WebGL batch, just like standard Sprites, so doesn't introduce any additional shader overhead. Because the Plane just generates vertices into the WebGL batch, like any other Sprite, you can use all of the common Game Object components on a Plane too, such as a custom pipeline, mask, blend mode or texture.

You can use the uvScroll and uvScale methods to adjust the placement and scaling of the texture if this Plane is using a single texture, and not a frame from a texture atlas or sprite sheet.

The Plane Game Object also has the Animation component, allowing you to play animations across the Plane just as you would with a Sprite.

While a Plane cannot be enabled for input it does have the methods hasFaceAt and getFaceAt which can be used with Pointer coordinates to detect if they have clicked on Plane face, or not.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Nine Slice Game Object

Phaser v3.60 contains a new native Nine Slice Game Object. A Nine Slice Game Object allows you to display a texture-based object that can be stretched both horizontally and vertically, but that retains fixed-sized corners. The dimensions of the corners are set via the parameters to the class. When you resize a Nine Slice Game Object only the middle sections of the texture stretch. This is extremely useful for UI and button-like elements, where you need them to expand to accommodate the content without distorting the texture.

The texture you provide for this Game Object should be based on the following layout structure:

A B +---+----------------------+---+ C | 1 | 2 | 3 | +---+----------------------+---+ | | | | | 4 | 5 | 6 | | | | | +---+----------------------+---+ D | 7 | 8 | 9 | +---+----------------------+---+

When changing this objects width and / or height:

areas 1, 3, 7 and 9 (the corners) will remain unscaled
areas 2 and 8 will be stretched horizontally only
areas 4 and 6 will be stretched vertically only
area 5 will be stretched both horizontally and vertically

You can also create a 3 slice Game Object:

This works in a similar way, except you can only stretch it horizontally. Therefore, it requires less configuration:

A B +---+----------------------+---+ | | | | C | 1 | 2 | 3 | | | | | +---+----------------------+---+

When changing this objects width (you cannot change its height)

areas 1 and 3 will remain unscaled
area 2 will be stretched horizontally

The above configuration concept is adapted from the Pixi NineSlicePlane.

To specify a 3 slice object instead of a 9 slice you should only provide the leftWidth and rightWidth parameters. To create a 9 slice you must supply all parameters.

The minimum width this Game Object can be is the total of leftWidth + rightWidth. 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 scale it.

In terms of performance, using a 3 slice Game Object is the equivalent of having 3 Sprites in a row. Using a 9 slice Game Object is the equivalent of having 9 Sprites in a row. The vertices of this object are all batched together and can co-exist with other Sprites and graphics on the display list, without incurring any additional overhead.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Pre FX Pipeline

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isPreFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Pre FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all PreFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Pre FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.
  • The WebGLPipeline.setTime method has a new optional parameter shader, which allows you to control the shader on which the time value is set.
  • If you add #define SHADER_NAME to the start of your shader then it will be picked up as the WebGLShader name during the setShadersFromConfig process within WebGLPipeline.
  • Calling setPostPipeline on a Game Object will now pass the pipelineData configuration object (if provided) to the pipeline instance being created.
  • PipelineManager.getPostPipeline now has an optional 3rd parameter, a config object that is passed to the pipeline instance in its constructor, which can be used by the pipeline during its set-up.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Updated Particle System

The Particle system has been mostly rewritten to give it a much needed overhaul. This makes the API cleaner, the Game Objects a lot more memory efficient and also introduces several great new features. In order to do this, we had to make some breaking changes. The largest being the way in which particles are now created.

Previously when you used the this.add.particles command it would create a ParticleEmitterManager instance. You would then use this to create an Emitter, which would actually emit the particles. While this worked and did allow a Manager to control multiple emitters we found that in discussion developers seldom used this feature and it was common for a Manager to own just one single Emitter.

In order to streamline memory and the display list we have removed the ParticleEmitterManager entirely. When you call this.add.particles you're now creating a ParticleEmitter instance, which is being added directly to the display list and can be manipulated just like any other Game Object, i.e. scaled, rotated, positioned, added to a Container, etc. It now extends the GameObject base class, meaning it's also an event emitter, which allowed us to create some handy new events for particles.

So, to create an emitter, you now give it an xy coordinate, a texture and an emitter configuration object (you can also set this later, but most commonly you'd do it on creation). I.e.:

js const emitter = this.add.particles(100, 300, 'flares', { frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

This will create a 'red flare' emitter at 100 x 300.

Prior to 3.60 it would have looked like:

```js const manager = this.add.particles('flares');

const emitter = manager.createEmitter({ x: 100, y: 300, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 }); ```

The change is quite subtle but makes a big difference internally.

The biggest real change is with the particle x/y coordinates. It's important to understand that if you define x/y coordinates within the emitter configuration, they will be relative to those given in the add.particles call:

js const emitter = this.add.particles(100, 300, 'flares', { x: 100, y: 100, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

In the above example the particles will emit from 200 x 400 in world space, because the emitter is at 100 x 300 and the particles emit from an offset of 100 x 100.

By making this change it now means you're able to do things like tween the x/y coordinates of the emitter (something you couldn't do before), or add a single emitter to a Container.

Other new features include:

Animated Particles

The Particle class now has an instance of the Animation State component within it. This allows a particle to play an animation when it is emitted, simply by defining it in the emitter config.

For example, this will make each particle play the 'Prism' animation on emission:

js const emitter = this.add.particles(400, 300, 'gems', { anim: 'prism' ... });

You can also allow it to select a random animation by providing an array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: [ 'prism', 'square', 'ruby', 'square' ] ... });

You've also the ability to cycle through the animations in order, so each new particle gets the next animation in the array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'square', 'ruby', 'square' ], cycle: true } ... });

Or even set a quantity. For example, this will emit 10 'prism' particles, then 10 'ruby' particles and then repeat:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'ruby' ], cycle: true, quantity: 10 } ... });

The Animations must have already been created in the Global Animation Manager and must use the same texture as the one bound to the Particle Emitter. Aside from this, you can still control them in the same way as any other particle - scaling, tinting, rotation, alpha, lifespan, etc.

Fast Forward Particle Time

  • You can now 'fast forward' a Particle Emitter. This can be done via either the emitter config, using the new advance property, or by calling the new ParticleEmitter.fastForward method. If, for example, you have an emitter that takes a few seconds to 'warm up' and get all the particles into position, this allows you to 'fast forward' the emitter to a given point in time. The value is given in ms. All standard emitter events and callbacks are still handled, but no rendering takes place during the fast-forward until it has completed.
  • The ParticleEmitter.start method has a new optional parameter advance that allows you to fast-forward the given amount of ms before the emitter starts flowing.

Particle Interpolation

  • It's now possible to create a new Interpolation EmitterOp. You do this by providing an array of values to interpolate between, along with the function name:

js const emitter = this.add.particles(0, 0, 'texture', { x: { values: [ 50, 500, 200, 800 ], interpolation: 'catmull' } ... });

This will interpolate the x property of each particle through the data set given, using a catmull rom interpolation function. You can also use linear or bezier functions. Interpolation can be combined with an ease type, which controls the progression through the time value. The related EmitterOpInterpolationConfig types have also been added.

Particle Emitter Duration

  • The Particle Emitter config has a new optional parameter duration:

js const emitter = this.add.particles(0, 0, 'texture', { speed: 24, lifespan: 1500, duration: 500 });

This parameter is used for 'flow' emitters only and controls how many milliseconds the emitter will run for before automatically turning itself off.

  • ParticleEmitter.duration is a new property that contains the duration that the Emitter will emit particles for in flow mode.
  • The ParticleEmitter.start method has a new optional parameter duration, which allows you to set the emitter duration when you call this method. If you do this, it will override any value set in the emitter configuration.
  • The ParticleEmitter.stop method has a new optional parameter kill. If set it will kill all alive particles immediately, rather than leaving them to die after their lifespan expires.

Stop After a set number of Particles

  • The Particle Emitter config has a new optional stopAfter property. This, combined with the frequency property allows you to control exactly how many particles are emitted before the emitter then stops:

js const emitter = this.add.particles(0, 0, 'texture', { x: { start: 400, end: 0 }, y: { start: 300, end: 0 }, lifespan: 3000, frequency: 250, stopAfter: 6, quantity: 1 });

In the above code the emitter will launch 1 particle (set by the quantity property) every 250 ms (set by the frequency property) and move it to xy 0x0. Once it has fired 6 particles (the stopAfter property) the emitter will stop and emit the COMPLETE event.

  • The stopAfter counter is reset each time you call the start or flow methods.

Particle Hold

  • You can configure a Particle to be frozen or 'held in place' after it has finished its lifespan for a set number of ms via the new hold configuration option:

js const emitter = this.add.particles(0, 0, 'texture', { lifespan: 2000, scale: { start: 0, end: 1 }, hold: 1000 ... });

The above will scale a Particle in from 0 to 1 over the course of its lifespan (2 seconds). It will then hold it on-screen for another second (1000 ms) before the Emitter recycles it and removes it from display.

Particle Emitter Events

  • The Particle Emitter will now fire 5 new events. Listen for the events as follows:

```js const emitter = this.add.particles(0, 0, 'flares');

emitter.on('start', (emitter) => { // emission started });

emitter.on('explode', (emitter, particle) => { // emitter 'explode' called });

emitter.on('deathzone', (emitter, particle, deathzone) => { // emitter 'death zone' called });

emitter.on('stop', (emitter) => { // emission has stopped });

emitter.on('complete', (emitter) => { // all particles fully dead }); ```

  • The Particles.Events.START event is fired whenever the Emitter begins emission of particles in flow mode. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.EXPLODE event is fired whenever the Emitter explodes a bunch of particles via the explode method. A reference to the ParticleEmitter and a reference to the most recently fired Particle instance are the two parameters.
  • The Particles.Events.DEATH_ZONE event is fired whenever a Particle is killed by a Death Zone. A reference to the ParticleEmitter, the killed Particle and the DeathZone that caused it are the 3 parameters.
  • The Particles.Events.STOP event is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call the stop method, or when an Emitter hits its duration or stopAfter limit. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.COMPLETE event is fired when the final alive particle expires.

Multiple Emit Zones

  • In v3.60 a Particle Emitter can now have multiple emission zones. Previously, an Emitter could have only a single emission zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addEmitZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addEmitZone({ type: 'edge', source: circle, quantity: 64 }); ```

  • When an Emitter has more than one emission zone, the Particles will cycle through the zones in sequence. For example, an Emitter with 3 zones would emit its first particle from zone 1, the second from zone 2, the third from zone 3, the fourth from zone 1, etc.
  • You can control how many particles are emitted from a single zone via the new total property. EdgeZone.total and RandomZone.total are new properties that control the total number of particles the zone will emit, before passing control over to the next zone in the list, if any. The default is -1.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeEmitZone is a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getEmitZone is a new method that Particles call when they are 'fired' in order to set their starting position, if any.
  • The property ParticleEmitter.emitZone has been removed. It has been replaced with the new ParticleEmitter.emitZones array-based property.

Multiple Death Zones

  • In v3.60 a Particle Emitter can now have multiple death zones. Previously, an Emitter could have only a single death zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addDeathZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addDeathZone({ type: 'onEnter', source: circle }); ```

  • When an Emitter has more than one Death Zone, the Particles will check themselves against all of the Death Zones, to see if any of them kills them.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeDeathZone is a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getDeathZone is a new method that Particles call when they are updated in order to check if they intersect with any of the Death Zones.
  • The property ParticleEmitter.deathZone has been removed. It has been replaced with the new ParticleEmitter.deathZones array-based property.

Particle Colors

  • You can now specify a new color property in the Emitter configuration. This takes the form of an array of hex color values that the particles will linearly interpolate between during theif lifetime. This allows you to now change the color of a particle from birth to death, which gives you far more control over your emitter visuals than ever before. You'd use it as follows:

js const flame = this.add.particles(150, 550, 'flares', { frame: 'white', color: [ 0xfacc22, 0xf89800, 0xf83600, 0x9f0404 ], colorEase: 'quad.out', lifespan: 2400, angle: { min: -100, max: -80 }, scale: { start: 0.70, end: 0, ease: 'sine.out' }, speed: 100, advance: 2000, blendMode: 'ADD' });

Here you can see the array of 4 colors it will interpolate through.

  • The new colorEase configuration property allows you to define the ease used to calculate the route through the interpolation. This can be set to any valid ease string, such as sine.out or quad.in, etc. If left undefined it will use linear as default.
  • EmitterColorOp is a brand new Emitter Op class that specifically controls the handling of color values, it extends EmitterOp and uses the same methods but configured for faster color interpolation.
  • If you define color in your config it will override any Emitter tint values you may have set. In short, use color if you wish to adjust the color of the particles during their lifespan and use tint if you wish to modify either the entire emitter at once, or the color of the particles on birth only.
  • ParticleEmitter.particleColor is a new property that allows you to get and set the particle color op value.
  • ParticleEmitter.colorEase is a new property that allows you to get and set the ease function used by the color op.

Particle Sort Order

  • You now have much more control over the sorting order of particles in an Emitter. You can set the new ParticleEmitter.sortProperty and sortOrderAsc properties to set how (and if) particles should be sorted prior to rendering. For example, setting sortProperty to y would mean that the particles will be sorted based on their y value prior to rendering. The sort order controls the order in which the particles are rendered. For example:

```js const emitter = this.add.particles(100, 300, 'blocks', { frame: 'redmonster', lifespan: 5000, angle: { min: -30, max: 30 }, speed: 150, frequency: 200 });

emitter.setSortProperty('y', true); ```

  • The new ParticleEmitter.setSortProperty method allows you to modify the sort property and order at run-time.
  • The new ParticleEmitter.setSortCallback method allows you to set a callback that will be invoked in order to sort the particles, rather than using the built-in one. This gives you complete freedom over the logic applied to particle render sorting.

Particle Bounds, Renderer Culling and Overlap

  • Particles now have the ability to calculate their bounding box, based on their position, scale, rotation, texture frame and the transform of their parent. You can call the new Particle.getBounds method to return the bounds, which also gets stored in the new Particle.bounds Rectangle property.
  • ParticleEmitter.getBounds is a new method that will return the bounds of the Emitter based on all currently active particles. Optional parameters allow you to pad out the bounds and/or advance time in the particle flow, to allow for a more accurate overall bounds generation.
  • ParticleEmitter.viewBounds is a new property that is a Geom Rectangle. Set this Rectangle to define the overall area the emitter will render to. If this area doesn't intersect with the Camera then the emitter will be culled from rendering. This allows you to populate large Scenes with active emitters that don't consume rendering resources even though they are offscreen. Use the new getBounds method to help define the viewBounds area.
  • ParticleEmitter.overlap is a new method that will run a rectangle intersection test against the given target and all alive particles, returning those that overlap in an array. The target can be a Rectangle Geometry object or an Arcade Physics Body.
  • Particle.kill is a new method that will set the life of the particle to zero, forcing it to be immediately killed on the next Particle Emitter update.
  • ParticleEmitter.getWorldTransformMatrix is a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.
  • ParticleEmitter.worldMatrix is a new property that holds a TransformMatrix used for bounds calculations.

Particle Emitter Bounds

  • Prior to v3.60 a Particle Emitter had a bounds property. This was a Rectangle and if a Particle hit any of its edges it would rebound off it based on the Particles bounce value. In v3.60 this action has been moved to a Particle Processor. You can still configure the bounds via the Emitter config using the bounds property, as before. And you can configure which faces collide via the collideLeft etc properties. However, the following internal changes have taken place:
  • ParticleBounds is a new Particle Processor class that handles updating the particles.
  • The ParticleEmitter.setBounds method has been replaced with ParticleEmitter.addParticleBounds which now returns a new ParticleBounds Particle Processor instance.
  • The ParticleEmitter.bounds property has been removed. Please see the addParticleBounds method if you wish to retain this object.
  • The ParticleEmitter.collideLeft property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideRight property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideTop property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideBottom property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The Particle.checkBounds method has been removed as it's now handled by the Particle Processors.

Particle Processors

  • ParticleProcessor is a new base class that you can use to create your own Particle Processors, which are special processors capable of manipulating the path of Particles based on your own logic or math. It provides the structure required to handle the processing of particles and should be used as a base for your own classes.
  • GravityWell now extends the new ParticleProcessor class.
  • ParticleEmitter.addParticleProcessor is a new method that allows you to add a Particle Processor instance to the Emitter. The old createGravityWell method now uses this.
  • ParticleEmitter.removeParticleProcessor is a new method that will remove a Particle Processor from an Emitter.
  • ParticleEmitter.processors is a new List property that contains all of the Particle Processors belonging to the Emitter.
  • The ParticleEmitter.wells property has been removed. You should now use the new processors property instead, they are functionally identical.
  • ParticleProcessor.update is the method that handles all of the particle manipulation. It now has a new 4th parameter t that is the normalized lifespan of the Particle being processed.

Particle System EmitterOp Breaking Changes and Updates:

All of the following properties have been replaced on the ParticleEmitter class. Previously they were EmitterOp instances. They are now public getter / setters, so calling, for example, emitter.particleX will now return a numeric value - whereas before it would return the EmitterOp instance. This gives developers a lot more freedom when using Particle Emitters. Before v3.60 it was impossible to do this, for example:

js this.tweens.add({ targets: emitter, particleX: 400 });

I.e. you couldn't tween an emitters particle spawn position by directly accessing its x and y properties. However, now that all EmitterOps are getters, you're free to do this, allowing you to be much more creative and giving a nice quality-of-life improvement.

If, however, your code used to access EmitterOps, you'll need to change it as follows:

```js // Phaser 3.55 emitter.x.onChange(value) // Phaser 3.60 emitter.particleX = value

// Phaser 3.55 let x = emitter.x.propertyValue // Phaser 3.60 let x = emitter.particleX

// Phaser 3.55 emitter.x.onEmit() emitter.x.onUpdate() // Phaser 3.60 emitter.ops.x.onEmit() emitter.ops.x.onUpdate() ```

All of following EmitterOp functions can now be found in the new ParticleEmitter.ops property and have been replaced with getters:

  • accelerationX
  • accelerationY
  • alpha
  • angle
  • bounce
  • color
  • delay
  • lifespan
  • maxVelocityX
  • maxVelocityY
  • moveToX
  • moveToY
  • quantity
  • rotate
  • scaleX
  • scaleY
  • speedX
  • speedY
  • tint
  • x
  • y

Which means you can now directly access, modify and tween any of the above emitter properties at run-time while the emitter is active.

Another potentially breaking change is the removal of two internal private counters. These should never have been used directly anyway, but they are:

  • ParticleEmitter._counter - Now available via ParticleEmitter.flowCounter
  • ParticleEmitter._frameCounter - Now available via ParticleEmitter.frameCounter
  • EmitterOp._onEmit is a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyEmit method, to ensure that the Emitter current property remains current.
  • EmitterOp._onUpdate is a new private reference to the update callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyUpdate method, to ensure that the Emitter current property remains current.
  • EmitterOp.destroy is a new method that nulls all references. This is called automatically when a ParticleEmitter is itself destroyed.

Further Particle System Updates and Fixes:

  • The Particle DeathZone.willKill method now takes a Particle instance as its only parameter, instead of x and y coordinates, allowing you to perform more complex checks before deciding if the Particle should be killed, or not.
  • The Particle.resetPosition method has been renamed to setPosition and it now takes optional x/y parameters. If not given, it performs the same task as resetPosition did in earlier versions.
  • The ParticleEmitter class now has the AlphaSingle Component. This allows you to call setAlpha on the Emitter instance itself and have it impact all particles being rendered by it, allowing you to now 'fade in/out' a whole Emitter.
  • Setting frequency wasn't working correctly in earlier versions. It should allow you to specify a time, in ms, between which each 'quantity' of particles is emitted. However, the preUpdate loop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles.
  • Calling ParticleEmitter.start wouldn't reset the _frameCounter value internally, meaning the new emission didn't restart from the first texture frame again.
  • ParticleEmitter.counters is a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous _counter and _frameCounter properties have been merged into this array, along with new ones required for new features.
  • The WebGL Renderer will now use the new setQuad feature of the Transform Matrix. This vastly reduces the amount of math and function calls per particle, from 8 down to 1, increasing performance.
  • Particles with a scaleX or scaleY value of zero will no longer be rendered.
  • ParticleEmitter.preDestroy is a new method that will now clean-up all resources and internal arrays and destroy all Particles that the Emitter owns and clean-up all external references.
  • Particle.destroy is a new method that will clean up all external references and destroy the Animation State controller.
  • The ParticleEmitter._frameLength property is now specified on the class, rather than added dynamically at run-time, helping preserve class shape.
  • The ParticleEmitter.defaultFrame property has been removed as it's not required.
  • Calling ParticleEmitter.setFrame no longer resets the internal _frameCounter value to zero. Instead, the counter comparison has been hardened to >= instead of === to allow this value to change mid-emission and never reach the total.
  • The ParticleEmitter.configFastMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • The ParticleEmitter.configOpMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • Particle.scene is a new property that references the Scene the Particle Emitter belongs to.
  • Particle.anims is a new property that is an instance of the AnimationState component.
  • Particle.emit is a new proxy method that passes all Animation related events through to the Particle Emitter Manager to emit, as Particles cannot emit events directly.
  • Particle.isCropped is a new read-only property. Do not modify.
  • Particle.setSizeToFrame is a new internal NOOP method. Do not call.
  • ParticleEmitter.anims is a new property that contains the Animation keys that can be assigned to Particles.
  • ParticleEmitter.currentAnim is a new property that contains the index of the current animation, as tracked in cycle playback.
  • ParticleEmitter.randomAnim is a new boolean property that controls if the animations are selected randomly, or in a cycle.
  • ParticleEmitter.animQuantity is a new property that controls the number of consecutive particles that are emitted with the current animation.
  • ParticleEmitter.counters is a new internal Float32Array that holds all the counters the Emitter uses.
  • ParticleEmitter.getAnim is a new method, called by Particles when they are emitted, that will return the animation to use, if any.
  • ParticleEmitter.setAnim is a new method, called with the Emitter Manager, that sets the animation data into the Emitter.
  • The Particles.EmitterOp.toJSON method will now JSON stringify the property value before returning it.
  • Particles.EmitterOp.method is a new property that holds the current operation method being used. This is a read-only numeric value.
  • Particles.EmitterOp.active is a new boolean property that defines if the operator is alive, or not. This is now used by the Emitter instead of nulling Emitter properties, helping maintain class shape.
  • Particles.EmitterOp.getMethod is a new internal method that returns the operation function being used as a numeric value. This is then cached in the method property.
  • The Particles.EmitterOp.setMethods method has been updated so it now has a non-optional 'method' parameter. It has also been rewritten to be much more efficient, now being just a single simple select/case block.
  • The Particles.EmitterOp.onChange method will now use the cached 'method' property to avoid running through the setMethods function if not required, allowing each Particle EmitterOp to skip a huge chunk of code.
  • We've also greatly improved the documentation around the Particle classes.
  • ParticleEmitter.setConfig is a new method that allows you to set the configuration of the Emitter. Previously this was known as fromJSON.
  • The ParticleEmitter.setPosition method no longer changes the position of the particle emission point, but of the Emitter itself.
  • The ParticleEmitter.setBounds method has been renamed to setParticleBounds.
  • The ParticleEmitter.setSpeed method has been renamed to setParticleSpeed.
  • The ParticleEmitter.setScale method has been renamed to setParticleScale as setScale will now set the scale of the whole Emitter.
  • The ParticleEmitter.setScaleX and setScaleY methods have been removed. Please use setParticleScale.
  • The ParticleEmitter.setGravity method has been renamed to setParticleGravity.
  • The ParticleEmitter.setGravityX and setGravityY methods have been removed. Please use setParticleGravity.
  • The ParticleEmitter.setAlpha method has been renamed to setParticleAlpha as setAlpha will now set the alpha of the whole Emitter.
  • The ParticleEmitter.setTint method has been renamed to setParticleTint.
  • The ParticleEmitter.setLifespan method has been renamed to setParticleLifespan.
  • The ParticleEmitter.on property has been renamed to emitting to avoid conflicts with the Event Emitter.
  • The ParticleEmitter.x property has been renamed to particleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.y property has been renamed to particleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleX property has been renamed to particleScaleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleY property has been renamed to particleScaleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.tint property has been renamed to particleTint and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.alpha property has been renamed to particleAlpha and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.angle property has been renamed to particleAngle and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.rotate property has been renamed to particleRotate and is a new EmitterOp capable of being tweened.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

TODO

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

  • The RenderTarget class will now create a Framebuffer that includes a Depth Stencil Buffer attachment by default. Previously, it didn't. By attaching a stencil buffer it allows things like Geometry Masks to work in combination with Post FX and other Pipelines. Fix #5802 (thanks @mijinc0)
  • When calling PipelineManager.clear and rebind it will now check if the vao extension is available, and if so, it'll bind a null vertex array. This helps clean-up from 3rd party libs that don't do this directly, such as ThreeJS.
  • The mipmapFilter property in the Game Config now defaults to '' (an empty string) instead of 'LINEAR'. The WebGLRenderer has been updated so that it will no longer create mipmaps at all with a default config. This potential saves a lot of VRAM (if your game has a lot of power-of-two textures) where before it was creating mipmaps that may never have been used. However, you may notice scaling doesn't look as crisp as it did before if you were using this feature without knowing it. To get it back, just add mipmapFilter: 'LINEAR' to your game config. Remember, as this is WebGL1 it only works with power-of-two sized textures.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • The batchLine method in the Multi Pipeline will now check to see if the dxdy len is zero, and if so, it will abort drawing the line. This fixes issues on older Android devices, such as the Samsung Galaxy S6 or Kindle 7, where it would draw erroneous lines leading up to the top-left of the canvas under WebGL when rendering a stroked rounded rectangle. Fix #5429 (thanks @fkoch-tgm @sreadixl)
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light fragment shader will now use the outTintEffect attribute meaning the Light Pipeline will now correctly light both tinted and fill-tinted Game Objects. Fix #5452 (thanks @kainage)
  • The Light Pipeline will now check to see if a Light2D enabled Game Object has a parent Container, or not, and factor the rotation and scale of this into the light calculation. Fix #6086 (thanks @irongaze)
  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been rewritten to help with performance, resolve some of its lingering issues and unifies the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • The Tween.seek method used to take a value between 0 and 1, based on how far through the Tween you wished to seek. However, it did not work with infinitely looping or repeating Tweens and would crash the browser tab. The new seek method takes a value in milliseconds instead and works perfectly on infinite Tweens.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as the source for a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • origin is now (0.5, 0.5) by default instead of (0, 0).

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Post Pipeline Updates

In order to add clarity in the codebase we have created a new PostPipeline Component and moved all of the relevant functions from the Pipeline component in to it. This leads to the following changes:

  • PostPipeline is a new Game Object Component that is now inherited by all Game Objects that are capable of using it.
  • Game Objects with the PostPipeline component now have a new property called postPipelineData. This object is used for storing Post Pipeline specific data in. Previously, both regular and post pipelines used the same pipelineData object, but this has now been split up for flexibility.
  • The Pipeline.resetPipeline method no longer has its first resetPostPipelines argument. It now has just one argument resetData so please be aware of this if you call this function anywhere in your code.
  • PostPipeline.initPostPipeline is a new method that should be called by any Game Object that supports Post Pipelines.
  • The following Game Objects now have the new PostPipeline Component exclusively: Container and Layer.

Input System Updates

There are breaking changes from previous versions of Phaser.

  • The InteractiveObject.alwaysEnabled property has been removed. It is no longer checked within the InputPlugin and setting it will have no effect. This property has not worked correctly since version 3.52 when the new render list was implemented. Upon further investigation we decided to remove the property entirely, rather than shoe-horn it into the render list. If you need to create a non-rendering Interactive area, use the Zone Game Object instead.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.
  • The GameObjects.Components.Mask.createBitmapMask method can now accept the x, y, texture and frame parameters new to the BitmapMask constructor.
  • Previously, calling createBitmapMask on a Shape Game Object would fail unless you passed the shape to the method. Now, it will correctly create a mask from the Shape without needing to pass it. Fix #5976 (thanks @samme)

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • The Arcade Physics World has a new property tileFilterOptions which is an object passed to the GetTilesWithin methods used by the Sprite vs. Tilemap collision functions. These filters dramatically reduce the quantity of tiles being checked for collision, potentially saving thousands of redundant math comparisons from taking place.
  • The Graphics.strokeRoundedRect and fillRoundedRect methods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow)
  • AnimationManager.getAnimsFromTexture is a new method that will return all global Animations, as stored in the Animation Manager, that have at least one frame using the given Texture. This will not include animations created directly on local Sprites.
  • BitmapText.setLineSpacing is a new method that allows you to set the vertical spacing between lines in multi-line BitmapText Game Objects. It works in the same was as spacing for Text objects and the spacing value can be positive or negative. See also BitmapText.lineSpacing for the property rather than the method.
  • WebGLPipeline.vertexAvailable is a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.
  • The Tilemap and TilemapLayer classes have a new method getTileCorners. This method will return an array of Vector2s with each entry corresponding to the corners of the requested tile, in world space. This currently works for Orthographic and Hexagonal tilemaps.
  • BaseSoundManager.getAllPlaying is a new method that will return all currently playing sounds in the Sound Manager.
  • Animation.showBeforeDelay is a new optional boolean property you can set when creating, or playing an animation. If the animation has a delay before playback starts this controls if it should still set the first frame immediately, or after the delay has expired (the default).
  • InputPlugin.resetPointers is a new method that will loop through all of the Input Manager Pointer instances and reset them all. This is useful if a 3rd party component, such as Vue, has stolen input from Phaser and you need to reset its input state again.
  • Pointer.reset is a new method that will reset a Pointer instance back to its 'factory' settings.
  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • Game.isPaused is a new boolean that tracks if the Game loop is paused, or not (and can also be toggled directly)
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • The GetBounds.getCenter method now has an optional includeParent argument, which allows you to get the value in world space.
  • The MatterTileBody class, which is created when you convert a Tilemap into a Matter Physics world, will now check to see if the Tile has flipX or flipY set on it and rotate the body accordingly. Fix #5893 (thanks @Olliebrown @phaserhelp)
  • The BaseCamera has had its Alpha component replaced with AlphaSingle. Previously you had access to properties such as alphaTopLeft that never worked, now it correctly has just a single alpha property (thanks @samme)
  • Time.Clock.startTime is a new property that stores the time the Clock (and therefore the Scene) was started. This can be useful for comparing against the current time to see how much real world time has elapsed (thanks @samme)
  • ColorMatrix._matrix and _data are now Float32Arrays.
  • Calling the ColorMatrix.set, reset and getData methods all now use the built-in Float32 Array operations, making them considerably faster.
  • ColorMatrix.BLACK_WHITE is a new constant used by blackwhite operations.
  • ColorMatrix.NEGATIVE is a new constant used by negative operations.
  • ColorMatrix.DESATURATE_LUMINANCE is a new constant used by desaturation operations.
  • ColorMatrix.SEPIA is a new constant used by sepia operations.
  • ColorMatrix.LSD is a new constant used by LSD operations.
  • ColorMatrix.BROWN is a new constant used by brown operations.
  • ColorMatrix.VINTAGE is a new constant used by vintage pinhole operations.
  • ColorMatrix.KODACHROME is a new constant used by kodachrome operations.
  • ColorMatrix.TECHNICOLOR is a new constant used by technicolor operations.
  • ColorMatrix.POLAROID is a new constant used by polaroid operations.
  • ColorMatrix.SHIFT_BGR is a new constant used by shift BGR operations.
  • If no Audio URLs match the given device a new warning is now displayed in the console (thanks @samme)
  • Texture.has will now return a strict boolean, rather than an object that can be cooerced into a boolean (thanks @samme)
  • The CanvasTexture.draw method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The CanvasTexture.drawFrame method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The CanvasTexture.clear method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The Game.registry, which is a DataManager instance that can be used as a global store of game wide data will now use its own Event Emitter, instead of the Game's Event Emitter. This means it's perfectly safe for you to now use the Registry to emit and listen for your own custom events without conflicting with events the Phaser Game instance emits.
  • The GenerateVerts function has a new optional parameter flipUV which, if set, will flip the UV texture coordinates (thanks cedarcantab)
  • The GenerateVerts function no longer errors if the verts and uvs arrays are not the same size and containsZ is true (thanks cedarcantab)
  • The Device.Browser checks for Opera and Edge have been updated to use the more modern user agent strings those browsers now use. This breaks compatibility with really old versions of those browsers but fixes it for modern ones (which is more important) (thanks @ ArtemSiz)
  • The SceneManager.processQueue method will no longer return if a new Scene was added, after starting it. This allows any other queued operations to still be run in the same frame, rather than being delayed until the next game frame. Fix #5359 (thanks @telinc1)
  • Camera.scrollX and scrollY will now only set the Camera.dirty flag to true if the new value given to them is different from their current value. This allows you to use this property in your own culling functions. Fix #6088 (thanks @Waclaw-I)
  • Face.update is a new method that updates each of the Face vertices. This is now called internally by Face.isInView.
  • Vertex.resize is a new method that will set the position and then translate the Vertex based on an identity matrix.
  • The Vertex.update method now returns this to allow it to be chained.
  • You can now optionally specify the maxSpeed value in the Arcade Physics Group config (thanks @samme)
  • You can now optionally specify the useDamping boolean in the Arcade Physics Group config (thanks @samme)
  • Removed the HexagonalTileToWorldY function as it cannot work without an X coordinate. Use HexagonalTileToWorldXY instead.
  • Removed the HexagonalWorldToTileY function as it cannot work without an X coordinate. Use HexagonalWorldToTileXY instead.
  • Earcut has been updated to version 2.2.4. This release improves performance by 10-15% and fixes 2 rare race conditions that could leave to infinite loops. Earcut is used internally by Graphics and Shape game objects when triangulating polygons for complex shapes.
  • The BaseSoundManager.getAll method used to require a key parameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned.
  • The WebAudioSoundManager will now detect if the Audio Context enters a 'suspended' or 'interrupted' state as part of its update loop and if so it'll try to resume the context. This can happen if you change or disable the audio device, such as plugging in headphones with built-in audio drivers then disconnecting them, or swapping tabs on iOS. Fix #5353 (thanks @helloyoucan)
  • The CONTEXT_RESTORED Game Event has been removed and the WebGL Renderer no longer listens for the contextrestored DOM event, or has a contextRestoredHandler method. This never actually worked properly, in any version of Phaser 3 - although the WebGLRenderer would be restored, none of the shaders, pipelines or textures were correctly re-created. If a context is now lost, Phaser will display an error in the console and all rendering will halt. It will no longer try to re-create the context, leading to masses of WebGL errors in the console. Instead, it will die gracefully and require a page reload.
  • The Text and TileSprite Game Objects no longer listen for the CONTEXT_RESTORED event and have had their onContextRestored methods removed.
  • Scenes.Systems.canInput is a new internal method that determines if a Scene can receive Input events, or not. This is now used by the InputPlugin instead of the previous isActive test. This allows a Scene to emit and handle input events even when it is running init or preload. Previously, it could only do this after create had finished running. Fix #6123 (thanks @yaasinhamidi)
  • The BitmapText Game Object has two new read-only properties displayWidth and displayHeight. This allows the BitmapText to correctly use the GetBounds component.
  • The BitmapText Game Object now has the GetBounds component added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames)
  • WebGLSnapshot will now flip the pixels in the created Image element if the source was a framebuffer. This means grabbing a snapshot from a Dynamic or Render Texture will now correctly invert the pixels on the y axis for an Image. Grabbing from the game renderer will skip this.
  • WebGLRenderer.snapshotFramebuffer and by extension, the snapshot methods in Dynamic Textures and Render Textures, has been updated to ensure that the width and height never exceed the framebuffer dimensions, or it'll cause a runtime error. The method snapshotArea has had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)
  • Animation.stop is always called when a new animation is loaded, regardless if the animation was playing or not and the delayCounter is reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)
  • ScaleManager.listeners has been renamed to domlisteners to avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)
  • Geom.Intersects.LineToLine will no longer create an internal Point object, as it's not required internally (thanks @Trissolo)
  • The tempZone used by GridAlign has now had setOrigin(0, 0) applied to it. This leads to more accurate / expected zone placement when aligning grid items.
  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • The TilemapLayer.skipCull feature wasn't being applied correctly for Isometric, Hexagonal or Staggered tiles, only for Orthographic tiles (the default). It will now respect the skipCull property and return all tiles during culling if enabled. Fix #5524 (thanks @veleek)
  • Shutting down a Scene that didn't have the LoaderPlugin would throw an error when removing event handlers. It now checks first, before removing (thanks @samme)
  • The Container.getBounds method will now use getTextBounds if one of its children is a BitmapText Game Object, giving more accurate bounds results (thanks @EmilSV)
  • The renderFlags property, used to determine if a Game Object will render, or not, would be calculated incorrectly depending on the order of the scaleX and scaleY properties. It now works regardless of the order (thanks @mizunokazumi)
  • The SpriteSheetFromAtlas parser was using the incorrect sourceIndex to grab frames from a given texture. This caused a crash whenever a trimmed spritesheet was added from any multiatlas image other than the first (thanks @Bambosh)
  • The maxSpeed setting in Arcade Physics wasn't recalculated during the Body update, prior to being compared, leading to inconsistent results. Fix #6329 (thanks @Bambosh)
  • Several paths have been fixed in the phaser-core.js entry point (thanks @pavle-goloskokovic)
  • When a Game Object had Input Debug Enabled the debug image would be incorrectly offset if the Game Object was attached to was scaled and the hit area shape was smaller, or offset, from the Game Object. Fix #4905 #6317 (thanks @PavelMishin @justinlueders)
  • An inactive Scene is no longer updated after a Scene transition completes. Previously, it will still update the Scene one final time. This fix also prevents the POST_UPDATE event from firing after the transition is over. Fix #5550 (thanks @mijinc0 @samme)
  • Although not recommended, when adding a Layer Game Object to another Layer Game Object, it will no longer error because it cannot find the removeFromDisplayList function. Fix #5595 (thanks @tringcooler)
  • The Actions.Spread method will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV)
  • Calling setDisplayOrigin on a Video Game Object would cause the origins to be set to NaN if the Video was created without an asset key. It will now give Videos a default size, preventing this error, which is reset once a video is loaded. Fix #5560 (thanks @mattjennings)
  • When ImageFile loads with a linked Normal Map and the map completes first, but the Image is still in a pending state, it would incorrectly add itself to the cache instead of waiting. It now checks this process more carefully. Fix #5886 (thanks @inmylo)
  • Using a dataKey to specify a part of a JSON file when using load.pack would fail as it wouldn't correctly assign the right part of the pack file to the Loader. You can now use this parameter properly. Fix #6001 (thanks @rexrainbow)
  • The Text.advancedWordWrap function would incorrectly merge the current and next lines when wrapping words with carriage-returns in. Fix #6187 (thanks @Ariorh1337 @robinheidrich)
  • Recoded the point conversion math in the HexagonalTileToWorldXY function as it was incorrect. Now returns world coordinates correctly.
  • Tilemap.copy would error if you copied a block of tiles over itself, even partially, as it tried to copy already replaced tiles as part of the function. It will now copy correctly, regardless of source or destination areas. Fix #6188 (thanks @Arkyris)
  • Tile.copy will now use the DeepCopy function to copy the Tile.properties object, as otherwise it just gets copied by reference.
  • Recoded the point conversion math in the HexagonalWorldToTileXY function as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich)
  • Fixed the point conversion math in the IsometricWorldToTileXY function and added optional boolean property that allows the setting of the tile origin to the top or base. Fix #5781 (thanks @benjamin-wilson)
  • Calling Tilemap.worldToTileX or worldToTileY on a Isometric or Hexagonal Tilemap will now always return null instead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should use worldToTileXY instead.
  • The Game.headlessStep method will now reset SceneManager.isProcessing before PRE_RENDER. This fixes issues in HEADLESS mode where the Scene Manager wouldn't process additionally added Scenes created after the Game had started. Fix #5872 #5974 (thanks @micsun-al @samme)
  • If Rope.setPoints was called with the exact same number of points as before, it wouldn't set the dirty flag, meaning the vertices were not updated on the next render (thanks @stupot)
  • Particle.fire will now check to see if the parent Emitter is set to follow a Game Object and if so, and if the x/y EmitterOps are spread ops, then it'll space the particles out based on the follower coordinates, instead of clumping them all together. Fix #5847 (thanks @sreadixl)
  • When using RTL (right-to-left) Text Game Objects, the Text would vanish on iOS15+ if you changed the text or font style. The context RTL properties are now restored when the text is updated, fixing this issue. Fix #6121 (thanks @liorGameDev)
  • The Tilemap.destroyLayer method would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme)
  • MapData and ObjectLayer will now enforce that the Tilemap.objects property is always an array. Sometimes Tiled willl set it to be a blank object in the JSON data. This fix makes sure it is always an array. Fix #6139 (thanks @robbeman)
  • The ParseJSONTiled function will now run a DeepCopy on the source Tiled JSON, which prevents object mutation, fixing an issue where Tiled Object Layer names would be duplicated if used across multiple Tilemap instances. Fix #6212 (thanks @temajm @wahur666)
  • The method Color.setFromHSV would not change the members h, s and v, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow)
  • When calling GameObject.getPostPipeline and passing in a string for the pipeline name it would error with 'Uncaught TypeError: Right-hand side of 'instanceof' is not an object'. This is now handled correctly internally (thanks @neki-dev)
  • When playing a chained animation, the nextAnim property could get set to undefined which would stop the next animation in the queue from being set. The check now handles all falsey cases. Fix #5852 (thanks @Pythux)
  • When calling InputPlugin.clear it will now call removeDebug on the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton)
  • The Video.loadURL method wouldn't load the video or emit the VIDEO_CREATED event unless noAudio was specified. A load event handler has been added to resolve this (thanks @samme)
  • If you create a repeating or looping TimerEvent with a delay of zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan)
  • The endFrame and startFrame properties of the SpriteSheet parser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the given startFrame so that is frame zero and end at endFrame, regardless how many other frames are in the sheet.
  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fai

- JavaScript
Published by photonstorm about 3 years ago

phaser - Phaser 3.60.0 Beta 20

Version 3.60.0 - Miku - in development

New Features - Built-in Special FX

We have decided to bundle a selection of highly flexible special effect shaders in to Phaser 3.60 and provide access to them via an easy to use set of API calls. The FX included are:

  • Barrel - A nice pinch / bulge distortion effect.
  • Bloom - Add bloom to any Game Object, with custom offset, blur strength, steps and color.
  • Blur - 3 different levels of gaussian blur (low, medium and high) and custom distance and color.
  • Bokeh / TiltShift - A bokeh and tiltshift effect, with intensity, contrast and distance settings.
  • Circle - Add a circular ring around any Game Object, useful for masking / avatar frames, with custom color, width and background color.
  • ColorMatrix - Add a ColorMatrix to any Game Object with access to all of its methods, such as sepia, greyscale, lsd and lots more.
  • Displacement - Use a displacement texture, such as a noise texture, to drastically (or subtly!) alter the appearance of a Game Object.
  • Glow - Add a smooth inner or outer glow, with custom distance, strength and color.
  • Gradient - Draw a gradient between two colors across any Game Object, with optional 'chunky' mode for classic retro style games.
  • Pixelate - Make any Game Object appear pixelated, to a varying degree.
  • Shadow - Add a drop shadow behind a Game Object, with custom depth and color.
  • Shine - Run a 'shine' effect across a Game Object, either additively or as part of a reveal.
  • Vignette - Apply a vignette around a Game Object, with custom offset position, radius and color.
  • Wipe - Set a Game Object to 'wipe' or 'reveal' with custom line width, direction and axis of the effect.

What's more, the FX can be stacked up. You could add, for example, a Barrel followed by a Blur and then topped-off with a Circle effect. Just by adjusting the ordering you can achieve some incredible and unique effects, very quickly.

We've worked hard to make the API as easy to use as possible, too. No more messing with pipelines or importing plugins. You can simply do:

```js const player = this.add.sprite(x, y, texture);

player.preFX.addGlow(0xff0000, 32); ```

This will add a 32 pixel red glow around the player Sprite.

Each effect returns a new FX Controller instance, allowing you to easily adjust the special effects in real-time via your own code, tweens and similar:

```js const fx = container.postFX.addWipe();

this.tweens.add({ targets: fx, progress: 1 }); ```

This will add a Wipe Effect to a Container instance and then tween its progress value from 0 to 1, causing the wipe to play out.

All texture-based Game Objects have access to Pre FX (so that includes Images, Sprites, TileSprites, Text, RenderTexture and Video). However, all Game Objects have access to Post FX, as do cameras. The difference is just when the effect is applied. For a 'pre' effect, it is applied before the Game Object is drawn. For a 'post' effect, it's applied after it has been drawn. All of the same effects are available to both.

js this.cameras.main.postFX.addTiltShift();

For example, this will apply a Tilt Shift effect to everything being rendered by the Camera. Which is a much faster way of doing it than applying the same effect to every child in a Scene. You can also apply them to Containers, allowing more fine-grained control over the display.

The full list of new methods are as follows:

Available only to texture-based Game Objects:

  • GameObject.preFX.addGlow adds a Glow Pre FX effect to the Game Object.
  • GameObject.preFX.addShadow adds a Shadow Pre FX effect to the Game Object.
  • GameObject.preFX.addPixelate adds a Pixelate Pre FX effect to the Game Object.
  • GameObject.preFX.addVignette adds a Vignette Pre FX effect to the Game Object.
  • GameObject.preFX.addShine adds a Shine Pre FX effect to the Game Object.
  • GameObject.preFX.addBlur adds a Blur Pre FX effect to the Game Object.
  • GameObject.preFX.addGradient adds a Gradient Pre FX effect to the Game Object.
  • GameObject.preFX.addBloom adds a Bloom Pre FX effect to the Game Object.
  • GameObject.preFX.addColorMatrix adds a ColorMatrix Pre FX effect to the Game Object.
  • GameObject.preFX.addCircle adds a Circle Pre FX effect to the Game Object.
  • GameObject.preFX.addBarrel adds a Barrel Pre FX effect to the Game Object.
  • GameObject.preFX.addDisplacement adds a Displacement Pre FX effect to the Game Object.
  • GameObject.preFX.addWipe adds a Wipe Pre FX effect to the Game Object.
  • GameObject.preFX.addReveal adds a Reveal Pre FX effect to the Game Object.
  • GameObject.preFX.addBokeh adds a Bokeh Pre FX effect to the Game Object.
  • GameObject.preFX.addTiltShift adds a TiltShift Pre FX effect to the Game Object.

Available to all Game Objects:

  • GameObject.postFX.addGlow adds a Glow Post FX effect to the Game Object.
  • GameObject.postFX.addShadow adds a Shadow Post FX effect to the Game Object.
  • GameObject.postFX.addPixelate adds a Pixelate Post FX effect to the Game Object.
  • GameObject.postFX.addVignette adds a Vignette Post FX effect to the Game Object.
  • GameObject.postFX.addShine adds a Shine Post FX effect to the Game Object.
  • GameObject.postFX.addBlur adds a Blur Post FX effect to the Game Object.
  • GameObject.postFX.addGradient adds a Gradient Post FX effect to the Game Object.
  • GameObject.postFX.addBloom adds a Bloom Post FX effect to the Game Object.
  • GameObject.postFX.addColorMatrix adds a ColorMatrix Post FX effect to the Game Object.
  • GameObject.postFX.addCircle adds a Circle Post FX effect to the Game Object.
  • GameObject.postFX.addBarrel adds a Barrel Post FX effect to the Game Object.
  • GameObject.postFX.addDisplacement adds a Displacement Post FX effect to the Game Object.
  • GameObject.postFX.addWipe adds a Wipe Post FX effect to the Game Object.
  • GameObject.postFX.addReveal adds a Reveal Post FX effect to the Game Object.
  • GameObject.postFX.addBokeh adds a Bokeh Post FX effect to the Game Object.
  • GameObject.postFX.addTiltShift adds a TiltShift Post FX effect to the Game Object.

New Features - Spatial Sound

Thanks to a contribution from @alxwest the Web Audio Sound system now supports spatial sound.

TODO - List all of the new properties and methods!

New Features - Spine 4 Support

Thanks to a contribution from @justintien we now have a Spine 4 Plugin available.

You can find it in the plugins/spine4.1 folder in the main repository. There are also a bunch of new npm scripts to help build this plugin:

npm run plugin.spine4.1.full.dist - To build new dist files for both canvas and WebGL. npm run plugin.spine4.1.dist - To build new dist files. npm run plugin.spine4.1.watch - To enter watch mode when doing dev work on the plugin. npm run plugin.spine4.1.runtimes - To build new versions of the Spine 4 runtimes.

The core plugin API remains largely the same. You can find lots of updated examples in the Phaser 3 Examples repo in the 3.60/spine4.1 folder.

We will maintain both the Spine 3 and 4 plugins for the forseeable future.

Additional Spine 3 Bug Fixes

  • Using drawDebug on a Spine Game Object to view its skeleton would cause the next object in the display list to be skipped for rendering, if it wasn't a Spine Game Object too. This is because the Spine 3 skeleton debug draw ends the spine batch but the Scene Renderer wasn't rebound. Fix #6380 (thanks @spayton)
  • The Spine Plugin add and make functions didn't clear and rebind the WebGL pipeline. This could cause two different visual issues: The first is that a Phaser Game Object (such as a Sprite) could be seen to change its texture to display the Spine atlas texture instead for a single frame, and then on the next pass revert back to normal again. The second issue is that if the Spine skeleton wasn't added to the display list, but just created (via addToScene: false) then the Sprite would take on the texture frame entirely from that point on. Fix #6362 (thanks @frissonlabs)
  • Previously, it wasn't possible for multiple Spine Atlases to use PNGs with the exact same filename, even if they were in different folders. The SpineFile loader has now been updated so that the always-unique Spine key is pre-pended to the filename, for example if the key was bonus and the PNG in the atlas was coin.png then the final key (as stored in the Texture Manager) is now bonus:coin.png. The SpinePlugin.getAtlasCanvas and getAtlasWebGL methods have been updated to reflect this change. Fix #6022 (thanks @orjandh)
  • If a SpineContainer had a mask applied to it and the next immediate item on the display list was another Spine object (outside of the Container) then it would fail to rebind the WebGL pipeline, causing the mask to break. It will now rebind the renderer at the end of the SpineContainer batch, no matter what, if it has a mask. Fix #5627 (thanks @FloodGames)

New Features - Plane Game Object

Phaser v3.60 contains a new native Plane Game Object. The Plane Game Object is a helper class that takes the Mesh Game Object and extends it, allowing for fast and easy creation of Planes. A Plane is a one-sided grid of cells, where you specify the number of cells in each dimension. The Plane can have a texture that is either repeated (tiled) across each cell, or applied to the full Plane.

The Plane can then be manipulated in 3D space, with rotation across all 3 axis.

This allows you to create effects not possible with regular Sprites, such as perspective distortion. You can also adjust the vertices on a per-vertex basis. Plane data becomes part of the WebGL batch, just like standard Sprites, so doesn't introduce any additional shader overhead. Because the Plane just generates vertices into the WebGL batch, like any other Sprite, you can use all of the common Game Object components on a Plane too, such as a custom pipeline, mask, blend mode or texture.

You can use the uvScroll and uvScale methods to adjust the placement and scaling of the texture if this Plane is using a single texture, and not a frame from a texture atlas or sprite sheet.

The Plane Game Object also has the Animation component, allowing you to play animations across the Plane just as you would with a Sprite.

While a Plane cannot be enabled for input it does have the methods hasFaceAt and getFaceAt which can be used with Pointer coordinates to detect if they have clicked on Plane face, or not.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Nine Slice Game Object

Phaser v3.60 contains a new native Nine Slice Game Object. A Nine Slice Game Object allows you to display a texture-based object that can be stretched both horizontally and vertically, but that retains fixed-sized corners. The dimensions of the corners are set via the parameters to the class. When you resize a Nine Slice Game Object only the middle sections of the texture stretch. This is extremely useful for UI and button-like elements, where you need them to expand to accommodate the content without distorting the texture.

The texture you provide for this Game Object should be based on the following layout structure:

A B +---+----------------------+---+ C | 1 | 2 | 3 | +---+----------------------+---+ | | | | | 4 | 5 | 6 | | | | | +---+----------------------+---+ D | 7 | 8 | 9 | +---+----------------------+---+

When changing this objects width and / or height:

areas 1, 3, 7 and 9 (the corners) will remain unscaled
areas 2 and 8 will be stretched horizontally only
areas 4 and 6 will be stretched vertically only
area 5 will be stretched both horizontally and vertically

You can also create a 3 slice Game Object:

This works in a similar way, except you can only stretch it horizontally. Therefore, it requires less configuration:

A B +---+----------------------+---+ | | | | C | 1 | 2 | 3 | | | | | +---+----------------------+---+

When changing this objects width (you cannot change its height)

areas 1 and 3 will remain unscaled
area 2 will be stretched horizontally

The above configuration concept is adapted from the Pixi NineSlicePlane.

To specify a 3 slice object instead of a 9 slice you should only provide the leftWidth and rightWidth parameters. To create a 9 slice you must supply all parameters.

The minimum width this Game Object can be is the total of leftWidth + rightWidth. 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 scale it.

In terms of performance, using a 3 slice Game Object is the equivalent of having 3 Sprites in a row. Using a 9 slice Game Object is the equivalent of having 9 Sprites in a row. The vertices of this object are all batched together and can co-exist with other Sprites and graphics on the display list, without incurring any additional overhead.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Pre FX Pipeline

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isPreFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Pre FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all PreFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Pre FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.
  • The WebGLPipeline.setTime method has a new optional parameter shader, which allows you to control the shader on which the time value is set.
  • If you add #define SHADER_NAME to the start of your shader then it will be picked up as the WebGLShader name during the setShadersFromConfig process within WebGLPipeline.
  • Calling setPostPipeline on a Game Object will now pass the pipelineData configuration object (if provided) to the pipeline instance being created.
  • PipelineManager.getPostPipeline now has an optional 3rd parameter, a config object that is passed to the pipeline instance in its constructor, which can be used by the pipeline during its set-up.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Updated Particle System

The Particle system has been mostly rewritten to give it a much needed overhaul. This makes the API cleaner, the Game Objects a lot more memory efficient and also introduces several great new features. In order to do this, we had to make some breaking changes. The largest being the way in which particles are now created.

Previously when you used the this.add.particles command it would create a ParticleEmitterManager instance. You would then use this to create an Emitter, which would actually emit the particles. While this worked and did allow a Manager to control multiple emitters we found that in discussion developers seldom used this feature and it was common for a Manager to own just one single Emitter.

In order to streamline memory and the display list we have removed the ParticleEmitterManager entirely. When you call this.add.particles you're now creating a ParticleEmitter instance, which is being added directly to the display list and can be manipulated just like any other Game Object, i.e. scaled, rotated, positioned, added to a Container, etc. It now extends the GameObject base class, meaning it's also an event emitter, which allowed us to create some handy new events for particles.

So, to create an emitter, you now give it an xy coordinate, a texture and an emitter configuration object (you can also set this later, but most commonly you'd do it on creation). I.e.:

js const emitter = this.add.particles(100, 300, 'flares', { frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

This will create a 'red flare' emitter at 100 x 300.

Prior to 3.60 it would have looked like:

```js const manager = this.add.particles('flares');

const emitter = manager.createEmitter({ x: 100, y: 300, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 }); ```

The change is quite subtle but makes a big difference internally.

The biggest real change is with the particle x/y coordinates. It's important to understand that if you define x/y coordinates within the emitter configuration, they will be relative to those given in the add.particles call:

js const emitter = this.add.particles(100, 300, 'flares', { x: 100, y: 100, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

In the above example the particles will emit from 200 x 400 in world space, because the emitter is at 100 x 300 and the particles emit from an offset of 100 x 100.

By making this change it now means you're able to do things like tween the x/y coordinates of the emitter (something you couldn't do before), or add a single emitter to a Container.

Other new features include:

Animated Particles

The Particle class now has an instance of the Animation State component within it. This allows a particle to play an animation when it is emitted, simply by defining it in the emitter config.

For example, this will make each particle play the 'Prism' animation on emission:

js const emitter = this.add.particles(400, 300, 'gems', { anim: 'prism' ... });

You can also allow it to select a random animation by providing an array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: [ 'prism', 'square', 'ruby', 'square' ] ... });

You've also the ability to cycle through the animations in order, so each new particle gets the next animation in the array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'square', 'ruby', 'square' ], cycle: true } ... });

Or even set a quantity. For example, this will emit 10 'prism' particles, then 10 'ruby' particles and then repeat:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'ruby' ], cycle: true, quantity: 10 } ... });

The Animations must have already been created in the Global Animation Manager and must use the same texture as the one bound to the Particle Emitter. Aside from this, you can still control them in the same way as any other particle - scaling, tinting, rotation, alpha, lifespan, etc.

Fast Forward Particle Time

  • You can now 'fast forward' a Particle Emitter. This can be done via either the emitter config, using the new advance property, or by calling the new ParticleEmitter.fastForward method. If, for example, you have an emitter that takes a few seconds to 'warm up' and get all the particles into position, this allows you to 'fast forward' the emitter to a given point in time. The value is given in ms. All standard emitter events and callbacks are still handled, but no rendering takes place during the fast-forward until it has completed.
  • The ParticleEmitter.start method has a new optional parameter advance that allows you to fast-forward the given amount of ms before the emitter starts flowing.

Particle Interpolation

  • It's now possible to create a new Interpolation EmitterOp. You do this by providing an array of values to interpolate between, along with the function name:

js const emitter = this.add.particles(0, 0, 'texture', { x: { values: [ 50, 500, 200, 800 ], interpolation: 'catmull' } ... });

This will interpolate the x property of each particle through the data set given, using a catmull rom interpolation function. You can also use linear or bezier functions. Interpolation can be combined with an ease type, which controls the progression through the time value. The related EmitterOpInterpolationConfig types have also been added.

Particle Emitter Duration

  • The Particle Emitter config has a new optional parameter duration:

js const emitter = this.add.particles(0, 0, 'texture', { speed: 24, lifespan: 1500, duration: 500 });

This parameter is used for 'flow' emitters only and controls how many milliseconds the emitter will run for before automatically turning itself off.

  • ParticleEmitter.duration is a new property that contains the duration that the Emitter will emit particles for in flow mode.
  • The ParticleEmitter.start method has a new optional parameter duration, which allows you to set the emitter duration when you call this method. If you do this, it will override any value set in the emitter configuration.
  • The ParticleEmitter.stop method has a new optional parameter kill. If set it will kill all alive particles immediately, rather than leaving them to die after their lifespan expires.

Stop After a set number of Particles

  • The Particle Emitter config has a new optional stopAfter property. This, combined with the frequency property allows you to control exactly how many particles are emitted before the emitter then stops:

js const emitter = this.add.particles(0, 0, 'texture', { x: { start: 400, end: 0 }, y: { start: 300, end: 0 }, lifespan: 3000, frequency: 250, stopAfter: 6, quantity: 1 });

In the above code the emitter will launch 1 particle (set by the quantity property) every 250 ms (set by the frequency property) and move it to xy 0x0. Once it has fired 6 particles (the stopAfter property) the emitter will stop and emit the COMPLETE event.

  • The stopAfter counter is reset each time you call the start or flow methods.

Particle Hold

  • You can configure a Particle to be frozen or 'held in place' after it has finished its lifespan for a set number of ms via the new hold configuration option:

js const emitter = this.add.particles(0, 0, 'texture', { lifespan: 2000, scale: { start: 0, end: 1 }, hold: 1000 ... });

The above will scale a Particle in from 0 to 1 over the course of its lifespan (2 seconds). It will then hold it on-screen for another second (1000 ms) before the Emitter recycles it and removes it from display.

Particle Emitter Events

  • The Particle Emitter will now fire 5 new events. Listen for the events as follows:

```js const emitter = this.add.particles(0, 0, 'flares');

emitter.on('start', (emitter) => { // emission started });

emitter.on('explode', (emitter, particle) => { // emitter 'explode' called });

emitter.on('deathzone', (emitter, particle, deathzone) => { // emitter 'death zone' called });

emitter.on('stop', (emitter) => { // emission has stopped });

emitter.on('complete', (emitter) => { // all particles fully dead }); ```

  • The Particles.Events.START event is fired whenever the Emitter begins emission of particles in flow mode. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.EXPLODE event is fired whenever the Emitter explodes a bunch of particles via the explode method. A reference to the ParticleEmitter and a reference to the most recently fired Particle instance are the two parameters.
  • The Particles.Events.DEATH_ZONE event is fired whenever a Particle is killed by a Death Zone. A reference to the ParticleEmitter, the killed Particle and the DeathZone that caused it are the 3 parameters.
  • The Particles.Events.STOP event is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call the stop method, or when an Emitter hits its duration or stopAfter limit. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.COMPLETE event is fired when the final alive particle expires.

Multiple Emit Zones

  • In v3.60 a Particle Emitter can now have multiple emission zones. Previously, an Emitter could have only a single emission zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addEmitZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addEmitZone({ type: 'edge', source: circle, quantity: 64 }); ```

  • When an Emitter has more than one emission zone, the Particles will cycle through the zones in sequence. For example, an Emitter with 3 zones would emit its first particle from zone 1, the second from zone 2, the third from zone 3, the fourth from zone 1, etc.
  • You can control how many particles are emitted from a single zone via the new total property. EdgeZone.total and RandomZone.total are new properties that control the total number of particles the zone will emit, before passing control over to the next zone in the list, if any. The default is -1.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeEmitZone is a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getEmitZone is a new method that Particles call when they are 'fired' in order to set their starting position, if any.
  • The property ParticleEmitter.emitZone has been removed. It has been replaced with the new ParticleEmitter.emitZones array-based property.

Multiple Death Zones

  • In v3.60 a Particle Emitter can now have multiple death zones. Previously, an Emitter could have only a single death zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addDeathZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addDeathZone({ type: 'onEnter', source: circle }); ```

  • When an Emitter has more than one Death Zone, the Particles will check themselves against all of the Death Zones, to see if any of them kills them.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeDeathZone is a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getDeathZone is a new method that Particles call when they are updated in order to check if they intersect with any of the Death Zones.
  • The property ParticleEmitter.deathZone has been removed. It has been replaced with the new ParticleEmitter.deathZones array-based property.

Particle Colors

  • You can now specify a new color property in the Emitter configuration. This takes the form of an array of hex color values that the particles will linearly interpolate between during theif lifetime. This allows you to now change the color of a particle from birth to death, which gives you far more control over your emitter visuals than ever before. You'd use it as follows:

js const flame = this.add.particles(150, 550, 'flares', { frame: 'white', color: [ 0xfacc22, 0xf89800, 0xf83600, 0x9f0404 ], colorEase: 'quad.out', lifespan: 2400, angle: { min: -100, max: -80 }, scale: { start: 0.70, end: 0, ease: 'sine.out' }, speed: 100, advance: 2000, blendMode: 'ADD' });

Here you can see the array of 4 colors it will interpolate through.

  • The new colorEase configuration property allows you to define the ease used to calculate the route through the interpolation. This can be set to any valid ease string, such as sine.out or quad.in, etc. If left undefined it will use linear as default.
  • EmitterColorOp is a brand new Emitter Op class that specifically controls the handling of color values, it extends EmitterOp and uses the same methods but configured for faster color interpolation.
  • If you define color in your config it will override any Emitter tint values you may have set. In short, use color if you wish to adjust the color of the particles during their lifespan and use tint if you wish to modify either the entire emitter at once, or the color of the particles on birth only.
  • ParticleEmitter.particleColor is a new property that allows you to get and set the particle color op value.
  • ParticleEmitter.colorEase is a new property that allows you to get and set the ease function used by the color op.

Particle Sort Order

  • You now have much more control over the sorting order of particles in an Emitter. You can set the new ParticleEmitter.sortProperty and sortOrderAsc properties to set how (and if) particles should be sorted prior to rendering. For example, setting sortProperty to y would mean that the particles will be sorted based on their y value prior to rendering. The sort order controls the order in which the particles are rendered. For example:

```js const emitter = this.add.particles(100, 300, 'blocks', { frame: 'redmonster', lifespan: 5000, angle: { min: -30, max: 30 }, speed: 150, frequency: 200 });

emitter.setSortProperty('y', true); ```

  • The new ParticleEmitter.setSortProperty method allows you to modify the sort property and order at run-time.
  • The new ParticleEmitter.setSortCallback method allows you to set a callback that will be invoked in order to sort the particles, rather than using the built-in one. This gives you complete freedom over the logic applied to particle render sorting.

Particle Bounds, Renderer Culling and Overlap

  • Particles now have the ability to calculate their bounding box, based on their position, scale, rotation, texture frame and the transform of their parent. You can call the new Particle.getBounds method to return the bounds, which also gets stored in the new Particle.bounds Rectangle property.
  • ParticleEmitter.getBounds is a new method that will return the bounds of the Emitter based on all currently active particles. Optional parameters allow you to pad out the bounds and/or advance time in the particle flow, to allow for a more accurate overall bounds generation.
  • ParticleEmitter.viewBounds is a new property that is a Geom Rectangle. Set this Rectangle to define the overall area the emitter will render to. If this area doesn't intersect with the Camera then the emitter will be culled from rendering. This allows you to populate large Scenes with active emitters that don't consume rendering resources even though they are offscreen. Use the new getBounds method to help define the viewBounds area.
  • ParticleEmitter.overlap is a new method that will run a rectangle intersection test against the given target and all alive particles, returning those that overlap in an array. The target can be a Rectangle Geometry object or an Arcade Physics Body.
  • Particle.kill is a new method that will set the life of the particle to zero, forcing it to be immediately killed on the next Particle Emitter update.
  • ParticleEmitter.getWorldTransformMatrix is a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.
  • ParticleEmitter.worldMatrix is a new property that holds a TransformMatrix used for bounds calculations.

Particle Emitter Bounds

  • Prior to v3.60 a Particle Emitter had a bounds property. This was a Rectangle and if a Particle hit any of its edges it would rebound off it based on the Particles bounce value. In v3.60 this action has been moved to a Particle Processor. You can still configure the bounds via the Emitter config using the bounds property, as before. And you can configure which faces collide via the collideLeft etc properties. However, the following internal changes have taken place:
  • ParticleBounds is a new Particle Processor class that handles updating the particles.
  • The ParticleEmitter.setBounds method has been replaced with ParticleEmitter.addParticleBounds which now returns a new ParticleBounds Particle Processor instance.
  • The ParticleEmitter.bounds property has been removed. Please see the addParticleBounds method if you wish to retain this object.
  • The ParticleEmitter.collideLeft property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideRight property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideTop property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideBottom property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The Particle.checkBounds method has been removed as it's now handled by the Particle Processors.

Particle Processors

  • ParticleProcessor is a new base class that you can use to create your own Particle Processors, which are special processors capable of manipulating the path of Particles based on your own logic or math. It provides the structure required to handle the processing of particles and should be used as a base for your own classes.
  • GravityWell now extends the new ParticleProcessor class.
  • ParticleEmitter.addParticleProcessor is a new method that allows you to add a Particle Processor instance to the Emitter. The old createGravityWell method now uses this.
  • ParticleEmitter.removeParticleProcessor is a new method that will remove a Particle Processor from an Emitter.
  • ParticleEmitter.processors is a new List property that contains all of the Particle Processors belonging to the Emitter.
  • The ParticleEmitter.wells property has been removed. You should now use the new processors property instead, they are functionally identical.
  • ParticleProcessor.update is the method that handles all of the particle manipulation. It now has a new 4th parameter t that is the normalized lifespan of the Particle being processed.

Particle System EmitterOp Breaking Changes and Updates:

All of the following properties have been replaced on the ParticleEmitter class. Previously they were EmitterOp instances. They are now public getter / setters, so calling, for example, emitter.particleX will now return a numeric value - whereas before it would return the EmitterOp instance. This gives developers a lot more freedom when using Particle Emitters. Before v3.60 it was impossible to do this, for example:

js this.tweens.add({ targets: emitter, particleX: 400 });

I.e. you couldn't tween an emitters particle spawn position by directly accessing its x and y properties. However, now that all EmitterOps are getters, you're free to do this, allowing you to be much more creative and giving a nice quality-of-life improvement.

If, however, your code used to access EmitterOps, you'll need to change it as follows:

```js // Phaser 3.55 emitter.x.onChange(value) // Phaser 3.60 emitter.particleX = value

// Phaser 3.55 let x = emitter.x.propertyValue // Phaser 3.60 let x = emitter.particleX

// Phaser 3.55 emitter.x.onEmit() emitter.x.onUpdate() // Phaser 3.60 emitter.ops.x.onEmit() emitter.ops.x.onUpdate() ```

All of following EmitterOp functions can now be found in the new ParticleEmitter.ops property and have been replaced with getters:

  • accelerationX
  • accelerationY
  • alpha
  • angle
  • bounce
  • color
  • delay
  • lifespan
  • maxVelocityX
  • maxVelocityY
  • moveToX
  • moveToY
  • quantity
  • rotate
  • scaleX
  • scaleY
  • speedX
  • speedY
  • tint
  • x
  • y

Which means you can now directly access, modify and tween any of the above emitter properties at run-time while the emitter is active.

Another potentially breaking change is the removal of two internal private counters. These should never have been used directly anyway, but they are:

  • ParticleEmitter._counter - Now available via ParticleEmitter.flowCounter
  • ParticleEmitter._frameCounter - Now available via ParticleEmitter.frameCounter
  • EmitterOp._onEmit is a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyEmit method, to ensure that the Emitter current property remains current.
  • EmitterOp._onUpdate is a new private reference to the update callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyUpdate method, to ensure that the Emitter current property remains current.
  • EmitterOp.destroy is a new method that nulls all references. This is called automatically when a ParticleEmitter is itself destroyed.

Further Particle System Updates and Fixes:

  • The Particle DeathZone.willKill method now takes a Particle instance as its only parameter, instead of x and y coordinates, allowing you to perform more complex checks before deciding if the Particle should be killed, or not.
  • The Particle.resetPosition method has been renamed to setPosition and it now takes optional x/y parameters. If not given, it performs the same task as resetPosition did in earlier versions.
  • The ParticleEmitter class now has the AlphaSingle Component. This allows you to call setAlpha on the Emitter instance itself and have it impact all particles being rendered by it, allowing you to now 'fade in/out' a whole Emitter.
  • Setting frequency wasn't working correctly in earlier versions. It should allow you to specify a time, in ms, between which each 'quantity' of particles is emitted. However, the preUpdate loop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles.
  • Calling ParticleEmitter.start wouldn't reset the _frameCounter value internally, meaning the new emission didn't restart from the first texture frame again.
  • ParticleEmitter.counters is a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous _counter and _frameCounter properties have been merged into this array, along with new ones required for new features.
  • The WebGL Renderer will now use the new setQuad feature of the Transform Matrix. This vastly reduces the amount of math and function calls per particle, from 8 down to 1, increasing performance.
  • Particles with a scaleX or scaleY value of zero will no longer be rendered.
  • ParticleEmitter.preDestroy is a new method that will now clean-up all resources and internal arrays and destroy all Particles that the Emitter owns and clean-up all external references.
  • Particle.destroy is a new method that will clean up all external references and destroy the Animation State controller.
  • The ParticleEmitter._frameLength property is now specified on the class, rather than added dynamically at run-time, helping preserve class shape.
  • The ParticleEmitter.defaultFrame property has been removed as it's not required.
  • Calling ParticleEmitter.setFrame no longer resets the internal _frameCounter value to zero. Instead, the counter comparison has been hardened to >= instead of === to allow this value to change mid-emission and never reach the total.
  • The ParticleEmitter.configFastMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • The ParticleEmitter.configOpMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • Particle.scene is a new property that references the Scene the Particle Emitter belongs to.
  • Particle.anims is a new property that is an instance of the AnimationState component.
  • Particle.emit is a new proxy method that passes all Animation related events through to the Particle Emitter Manager to emit, as Particles cannot emit events directly.
  • Particle.isCropped is a new read-only property. Do not modify.
  • Particle.setSizeToFrame is a new internal NOOP method. Do not call.
  • ParticleEmitter.anims is a new property that contains the Animation keys that can be assigned to Particles.
  • ParticleEmitter.currentAnim is a new property that contains the index of the current animation, as tracked in cycle playback.
  • ParticleEmitter.randomAnim is a new boolean property that controls if the animations are selected randomly, or in a cycle.
  • ParticleEmitter.animQuantity is a new property that controls the number of consecutive particles that are emitted with the current animation.
  • ParticleEmitter.counters is a new internal Float32Array that holds all the counters the Emitter uses.
  • ParticleEmitter.getAnim is a new method, called by Particles when they are emitted, that will return the animation to use, if any.
  • ParticleEmitter.setAnim is a new method, called with the Emitter Manager, that sets the animation data into the Emitter.
  • The Particles.EmitterOp.toJSON method will now JSON stringify the property value before returning it.
  • Particles.EmitterOp.method is a new property that holds the current operation method being used. This is a read-only numeric value.
  • Particles.EmitterOp.active is a new boolean property that defines if the operator is alive, or not. This is now used by the Emitter instead of nulling Emitter properties, helping maintain class shape.
  • Particles.EmitterOp.getMethod is a new internal method that returns the operation function being used as a numeric value. This is then cached in the method property.
  • The Particles.EmitterOp.setMethods method has been updated so it now has a non-optional 'method' parameter. It has also been rewritten to be much more efficient, now being just a single simple select/case block.
  • The Particles.EmitterOp.onChange method will now use the cached 'method' property to avoid running through the setMethods function if not required, allowing each Particle EmitterOp to skip a huge chunk of code.
  • We've also greatly improved the documentation around the Particle classes.
  • ParticleEmitter.setConfig is a new method that allows you to set the configuration of the Emitter. Previously this was known as fromJSON.
  • The ParticleEmitter.setPosition method no longer changes the position of the particle emission point, but of the Emitter itself.
  • The ParticleEmitter.setBounds method has been renamed to setParticleBounds.
  • The ParticleEmitter.setSpeed method has been renamed to setParticleSpeed.
  • The ParticleEmitter.setScale method has been renamed to setParticleScale as setScale will now set the scale of the whole Emitter.
  • The ParticleEmitter.setScaleX and setScaleY methods have been removed. Please use setParticleScale.
  • The ParticleEmitter.setGravity method has been renamed to setParticleGravity.
  • The ParticleEmitter.setGravityX and setGravityY methods have been removed. Please use setParticleGravity.
  • The ParticleEmitter.setAlpha method has been renamed to setParticleAlpha as setAlpha will now set the alpha of the whole Emitter.
  • The ParticleEmitter.setTint method has been renamed to setParticleTint.
  • The ParticleEmitter.setLifespan method has been renamed to setParticleLifespan.
  • The ParticleEmitter.on property has been renamed to emitting to avoid conflicts with the Event Emitter.
  • The ParticleEmitter.x property has been renamed to particleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.y property has been renamed to particleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleX property has been renamed to particleScaleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleY property has been renamed to particleScaleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.tint property has been renamed to particleTint and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.alpha property has been renamed to particleAlpha and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.angle property has been renamed to particleAngle and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.rotate property has been renamed to particleRotate and is a new EmitterOp capable of being tweened.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

TODO

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

  • The RenderTarget class will now create a Framebuffer that includes a Depth Stencil Buffer attachment by default. Previously, it didn't. By attaching a stencil buffer it allows things like Geometry Masks to work in combination with Post FX and other Pipelines. Fix #5802 (thanks @mijinc0)
  • When calling PipelineManager.clear and rebind it will now check if the vao extension is available, and if so, it'll bind a null vertex array. This helps clean-up from 3rd party libs that don't do this directly, such as ThreeJS.
  • The mipmapFilter property in the Game Config now defaults to '' (an empty string) instead of 'LINEAR'. The WebGLRenderer has been updated so that it will no longer create mipmaps at all with a default config. This potential saves a lot of VRAM (if your game has a lot of power-of-two textures) where before it was creating mipmaps that may never have been used. However, you may notice scaling doesn't look as crisp as it did before if you were using this feature without knowing it. To get it back, just add mipmapFilter: 'LINEAR' to your game config. Remember, as this is WebGL1 it only works with power-of-two sized textures.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • The batchLine method in the Multi Pipeline will now check to see if the dxdy len is zero, and if so, it will abort drawing the line. This fixes issues on older Android devices, such as the Samsung Galaxy S6 or Kindle 7, where it would draw erroneous lines leading up to the top-left of the canvas under WebGL when rendering a stroked rounded rectangle. Fix #5429 (thanks @fkoch-tgm @sreadixl)
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light fragment shader will now use the outTintEffect attribute meaning the Light Pipeline will now correctly light both tinted and fill-tinted Game Objects. Fix #5452 (thanks @kainage)
  • The Light Pipeline will now check to see if a Light2D enabled Game Object has a parent Container, or not, and factor the rotation and scale of this into the light calculation. Fix #6086 (thanks @irongaze)
  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been rewritten to help with performance, resolve some of its lingering issues and unifies the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • The Tween.seek method used to take a value between 0 and 1, based on how far through the Tween you wished to seek. However, it did not work with infinitely looping or repeating Tweens and would crash the browser tab. The new seek method takes a value in milliseconds instead and works perfectly on infinite Tweens.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as the source for a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • origin is now (0.5, 0.5) by default instead of (0, 0).

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Post Pipeline Updates

In order to add clarity in the codebase we have created a new PostPipeline Component and moved all of the relevant functions from the Pipeline component in to it. This leads to the following changes:

  • PostPipeline is a new Game Object Component that is now inherited by all Game Objects that are capable of using it.
  • Game Objects with the PostPipeline component now have a new property called postPipelineData. This object is used for storing Post Pipeline specific data in. Previously, both regular and post pipelines used the same pipelineData object, but this has now been split up for flexibility.
  • The Pipeline.resetPipeline method no longer has its first resetPostPipelines argument. It now has just one argument resetData so please be aware of this if you call this function anywhere in your code.
  • PostPipeline.initPostPipeline is a new method that should be called by any Game Object that supports Post Pipelines.
  • The following Game Objects now have the new PostPipeline Component exclusively: Container and Layer.

Input System Updates

There are breaking changes from previous versions of Phaser.

  • The InteractiveObject.alwaysEnabled property has been removed. It is no longer checked within the InputPlugin and setting it will have no effect. This property has not worked correctly since version 3.52 when the new render list was implemented. Upon further investigation we decided to remove the property entirely, rather than shoe-horn it into the render list. If you need to create a non-rendering Interactive area, use the Zone Game Object instead.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.
  • The GameObjects.Components.Mask.createBitmapMask method can now accept the x, y, texture and frame parameters new to the BitmapMask constructor.
  • Previously, calling createBitmapMask on a Shape Game Object would fail unless you passed the shape to the method. Now, it will correctly create a mask from the Shape without needing to pass it. Fix #5976 (thanks @samme)

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • The Graphics.strokeRoundedRect and fillRoundedRect methods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow)
  • AnimationManager.getAnimsFromTexture is a new method that will return all global Animations, as stored in the Animation Manager, that have at least one frame using the given Texture. This will not include animations created directly on local Sprites.
  • BitmapText.setLineSpacing is a new method that allows you to set the vertical spacing between lines in multi-line BitmapText Game Objects. It works in the same was as spacing for Text objects and the spacing value can be positive or negative. See also BitmapText.lineSpacing for the property rather than the method.
  • WebGLPipeline.vertexAvailable is a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.
  • The Tilemap and TilemapLayer classes have a new method getTileCorners. This method will return an array of Vector2s with each entry corresponding to the corners of the requested tile, in world space. This currently works for Orthographic and Hexagonal tilemaps.
  • BaseSoundManager.getAllPlaying is a new method that will return all currently playing sounds in the Sound Manager.
  • Animation.showBeforeDelay is a new optional boolean property you can set when creating, or playing an animation. If the animation has a delay before playback starts this controls if it should still set the first frame immediately, or after the delay has expired (the default).
  • InputPlugin.resetPointers is a new method that will loop through all of the Input Manager Pointer instances and reset them all. This is useful if a 3rd party component, such as Vue, has stolen input from Phaser and you need to reset its input state again.
  • Pointer.reset is a new method that will reset a Pointer instance back to its 'factory' settings.
  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • Game.isPaused is a new boolean that tracks if the Game loop is paused, or not (and can also be toggled directly)
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • The BaseCamera has had its Alpha component replaced with AlphaSingle. Previously you had access to properties such as alphaTopLeft that never worked, now it correctly has just a single alpha property (thanks @samme)
  • Time.Clock.startTime is a new property that stores the time the Clock (and therefore the Scene) was started. This can be useful for comparing against the current time to see how much real world time has elapsed (thanks @samme)
  • ColorMatrix._matrix and _data are now Float32Arrays.
  • Calling the ColorMatrix.set, reset and getData methods all now use the built-in Float32 Array operations, making them considerably faster.
  • ColorMatrix.BLACK_WHITE is a new constant used by blackwhite operations.
  • ColorMatrix.NEGATIVE is a new constant used by negative operations.
  • ColorMatrix.DESATURATE_LUMINANCE is a new constant used by desaturation operations.
  • ColorMatrix.SEPIA is a new constant used by sepia operations.
  • ColorMatrix.LSD is a new constant used by LSD operations.
  • ColorMatrix.BROWN is a new constant used by brown operations.
  • ColorMatrix.VINTAGE is a new constant used by vintage pinhole operations.
  • ColorMatrix.KODACHROME is a new constant used by kodachrome operations.
  • ColorMatrix.TECHNICOLOR is a new constant used by technicolor operations.
  • ColorMatrix.POLAROID is a new constant used by polaroid operations.
  • ColorMatrix.SHIFT_BGR is a new constant used by shift BGR operations.
  • If no Audio URLs match the given device a new warning is now displayed in the console (thanks @samme)
  • Texture.has will now return a strict boolean, rather than an object that can be cooerced into a boolean (thanks @samme)
  • The CanvasTexture.draw method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The CanvasTexture.drawFrame method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The CanvasTexture.clear method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The Game.registry, which is a DataManager instance that can be used as a global store of game wide data will now use its own Event Emitter, instead of the Game's Event Emitter. This means it's perfectly safe for you to now use the Registry to emit and listen for your own custom events without conflicting with events the Phaser Game instance emits.
  • The GenerateVerts function has a new optional parameter flipUV which, if set, will flip the UV texture coordinates (thanks cedarcantab)
  • The GenerateVerts function no longer errors if the verts and uvs arrays are not the same size and containsZ is true (thanks cedarcantab)
  • The Device.Browser checks for Opera and Edge have been updated to use the more modern user agent strings those browsers now use. This breaks compatibility with really old versions of those browsers but fixes it for modern ones (which is more important) (thanks @ ArtemSiz)
  • The SceneManager.processQueue method will no longer return if a new Scene was added, after starting it. This allows any other queued operations to still be run in the same frame, rather than being delayed until the next game frame. Fix #5359 (thanks @telinc1)
  • Camera.scrollX and scrollY will now only set the Camera.dirty flag to true if the new value given to them is different from their current value. This allows you to use this property in your own culling functions. Fix #6088 (thanks @Waclaw-I)
  • Face.update is a new method that updates each of the Face vertices. This is now called internally by Face.isInView.
  • Vertex.resize is a new method that will set the position and then translate the Vertex based on an identity matrix.
  • The Vertex.update method now returns this to allow it to be chained.
  • You can now optionally specify the maxSpeed value in the Arcade Physics Group config (thanks @samme)
  • You can now optionally specify the useDamping boolean in the Arcade Physics Group config (thanks @samme)
  • Removed the HexagonalTileToWorldY function as it cannot work without an X coordinate. Use HexagonalTileToWorldXY instead.
  • Removed the HexagonalWorldToTileY function as it cannot work without an X coordinate. Use HexagonalWorldToTileXY instead.
  • Earcut has been updated to version 2.2.4. This release improves performance by 10-15% and fixes 2 rare race conditions that could leave to infinite loops. Earcut is used internally by Graphics and Shape game objects when triangulating polygons for complex shapes.
  • The BaseSoundManager.getAll method used to require a key parameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned.
  • The WebAudioSoundManager will now detect if the Audio Context enters a 'suspended' or 'interrupted' state as part of its update loop and if so it'll try to resume the context. This can happen if you change or disable the audio device, such as plugging in headphones with built-in audio drivers then disconnecting them, or swapping tabs on iOS. Fix #5353 (thanks @helloyoucan)
  • The CONTEXT_RESTORED Game Event has been removed and the WebGL Renderer no longer listens for the contextrestored DOM event, or has a contextRestoredHandler method. This never actually worked properly, in any version of Phaser 3 - although the WebGLRenderer would be restored, none of the shaders, pipelines or textures were correctly re-created. If a context is now lost, Phaser will display an error in the console and all rendering will halt. It will no longer try to re-create the context, leading to masses of WebGL errors in the console. Instead, it will die gracefully and require a page reload.
  • The Text and TileSprite Game Objects no longer listen for the CONTEXT_RESTORED event and have had their onContextRestored methods removed.
  • Scenes.Systems.canInput is a new internal method that determines if a Scene can receive Input events, or not. This is now used by the InputPlugin instead of the previous isActive test. This allows a Scene to emit and handle input events even when it is running init or preload. Previously, it could only do this after create had finished running. Fix #6123 (thanks @yaasinhamidi)
  • The BitmapText Game Object has two new read-only properties displayWidth and displayHeight. This allows the BitmapText to correctly use the GetBounds component.
  • The BitmapText Game Object now has the GetBounds component added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames)
  • WebGLSnapshot will now flip the pixels in the created Image element if the source was a framebuffer. This means grabbing a snapshot from a Dynamic or Render Texture will now correctly invert the pixels on the y axis for an Image. Grabbing from the game renderer will skip this.
  • WebGLRenderer.snapshotFramebuffer and by extension, the snapshot methods in Dynamic Textures and Render Textures, has been updated to ensure that the width and height never exceed the framebuffer dimensions, or it'll cause a runtime error. The method snapshotArea has had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)
  • Animation.stop is always called when a new animation is loaded, regardless if the animation was playing or not and the delayCounter is reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)
  • ScaleManager.listeners has been renamed to domlisteners to avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)
  • Geom.Intersects.LineToLine will no longer create an internal Point object, as it's not required internally (thanks @Trissolo)
  • The tempZone used by GridAlign has now had setOrigin(0, 0) applied to it. This leads to more accurate / expected zone placement when aligning grid items.
  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • The Container.getBounds method will now use getTextBounds if one of its children is a BitmapText Game Object, giving more accurate bounds results (thanks @EmilSV)
  • The renderFlags property, used to determine if a Game Object will render, or not, would be calculated incorrectly depending on the order of the scaleX and scaleY properties. It now works regardless of the order (thanks @mizunokazumi)
  • The SpriteSheetFromAtlas parser was using the incorrect sourceIndex to grab frames from a given texture. This caused a crash whenever a trimmed spritesheet was added from any multiatlas image other than the first (thanks @Bambosh)
  • The maxSpeed setting in Arcade Physics wasn't recalculated during the Body update, prior to being compared, leading to inconsistent results. Fix #6329 (thanks @Bambosh)
  • Several paths have been fixed in the phaser-core.js entry point (thanks @pavle-goloskokovic)
  • When a Game Object had Input Debug Enabled the debug image would be incorrectly offset if the Game Object was attached to was scaled and the hit area shape was smaller, or offset, from the Game Object. Fix #4905 #6317 (thanks @PavelMishin @justinlueders)
  • An inactive Scene is no longer updated after a Scene transition completes. Previously, it will still update the Scene one final time. This fix also prevents the POST_UPDATE event from firing after the transition is over. Fix #5550 (thanks @mijinc0 @samme)
  • Although not recommended, when adding a Layer Game Object to another Layer Game Object, it will no longer error because it cannot find the removeFromDisplayList function. Fix #5595 (thanks @tringcooler)
  • The Actions.Spread method will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV)
  • Calling setDisplayOrigin on a Video Game Object would cause the origins to be set to NaN if the Video was created without an asset key. It will now give Videos a default size, preventing this error, which is reset once a video is loaded. Fix #5560 (thanks @mattjennings)
  • When ImageFile loads with a linked Normal Map and the map completes first, but the Image is still in a pending state, it would incorrectly add itself to the cache instead of waiting. It now checks this process more carefully. Fix #5886 (thanks @inmylo)
  • Using a dataKey to specify a part of a JSON file when using load.pack would fail as it wouldn't correctly assign the right part of the pack file to the Loader. You can now use this parameter properly. Fix #6001 (thanks @rexrainbow)
  • The Text.advancedWordWrap function would incorrectly merge the current and next lines when wrapping words with carriage-returns in. Fix #6187 (thanks @Ariorh1337 @robinheidrich)
  • Recoded the point conversion math in the HexagonalTileToWorldXY function as it was incorrect. Now returns world coordinates correctly.
  • Tilemap.copy would error if you copied a block of tiles over itself, even partially, as it tried to copy already replaced tiles as part of the function. It will now copy correctly, regardless of source or destination areas. Fix #6188 (thanks @Arkyris)
  • Tile.copy will now use the DeepCopy function to copy the Tile.properties object, as otherwise it just gets copied by reference.
  • Recoded the point conversion math in the HexagonalWorldToTileXY function as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich)
  • Fixed the point conversion math in the IsometricWorldToTileXY function and added optional boolean property that allows the setting of the tile origin to the top or base. Fix #5781 (thanks @benjamin-wilson)
  • Calling Tilemap.worldToTileX or worldToTileY on a Isometric or Hexagonal Tilemap will now always return null instead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should use worldToTileXY instead.
  • The Game.headlessStep method will now reset SceneManager.isProcessing before PRE_RENDER. This fixes issues in HEADLESS mode where the Scene Manager wouldn't process additionally added Scenes created after the Game had started. Fix #5872 #5974 (thanks @micsun-al @samme)
  • If Rope.setPoints was called with the exact same number of points as before, it wouldn't set the dirty flag, meaning the vertices were not updated on the next render (thanks @stupot)
  • Particle.fire will now check to see if the parent Emitter is set to follow a Game Object and if so, and if the x/y EmitterOps are spread ops, then it'll space the particles out based on the follower coordinates, instead of clumping them all together. Fix #5847 (thanks @sreadixl)
  • When using RTL (right-to-left) Text Game Objects, the Text would vanish on iOS15+ if you changed the text or font style. The context RTL properties are now restored when the text is updated, fixing this issue. Fix #6121 (thanks @liorGameDev)
  • The Tilemap.destroyLayer method would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme)
  • MapData and ObjectLayer will now enforce that the Tilemap.objects property is always an array. Sometimes Tiled willl set it to be a blank object in the JSON data. This fix makes sure it is always an array. Fix #6139 (thanks @robbeman)
  • The ParseJSONTiled function will now run a DeepCopy on the source Tiled JSON, which prevents object mutation, fixing an issue where Tiled Object Layer names would be duplicated if used across multiple Tilemap instances. Fix #6212 (thanks @temajm @wahur666)
  • The method Color.setFromHSV would not change the members h, s and v, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow)
  • When calling GameObject.getPostPipeline and passing in a string for the pipeline name it would error with 'Uncaught TypeError: Right-hand side of 'instanceof' is not an object'. This is now handled correctly internally (thanks @neki-dev)
  • When playing a chained animation, the nextAnim property could get set to undefined which would stop the next animation in the queue from being set. The check now handles all falsey cases. Fix #5852 (thanks @Pythux)
  • When calling InputPlugin.clear it will now call removeDebug on the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton)
  • The Video.loadURL method wouldn't load the video or emit the VIDEO_CREATED event unless noAudio was specified. A load event handler has been added to resolve this (thanks @samme)
  • If you create a repeating or looping TimerEvent with a delay of zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan)
  • The endFrame and startFrame properties of the SpriteSheet parser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the given startFrame so that is frame zero and end at endFrame, regardless how many other frames are in the sheet.
  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created

- JavaScript
Published by photonstorm about 3 years ago

phaser - Phaser 3.60 Beta 19

Version 3.60.0 - Miku - in development

New Features - Built-in Special FX

We have decided to bundle a selection of highly flexible special effect shaders in to Phaser 3.60 and provide access to them via an easy to use set of API calls. The FX included are:

  • Barrel - A nice pinch / bulge distortion effect.
  • Bloom - Add bloom to any Game Object, with custom offset, blur strength, steps and color.
  • Blur - 3 different levels of gaussian blur (low, medium and high) and custom distance and color.
  • Bokeh / TiltShift - A bokeh and tiltshift effect, with intensity, contrast and distance settings.
  • Circle - Add a circular ring around any Game Object, useful for masking / avatar frames, with custom color, width and background color.
  • ColorMatrix - Add a ColorMatrix to any Game Object with access to all of its methods, such as sepia, greyscale, lsd and lots more.
  • Displacement - Use a displacement texture, such as a noise texture, to drastically (or subtly!) alter the appearance of a Game Object.
  • Glow - Add a smooth inner or outer glow, with custom distance, strength and color.
  • Gradient - Draw a gradient between two colors across any Game Object, with optional 'chunky' mode for classic retro style games.
  • Pixelate - Make any Game Object appear pixelated, to a varying degree.
  • Shadow - Add a drop shadow behind a Game Object, with custom depth and color.
  • Shine - Run a 'shine' effect across a Game Object, either additively or as part of a reveal.
  • Vignette - Apply a vignette around a Game Object, with custom offset position, radius and color.
  • Wipe - Set a Game Object to 'wipe' or 'reveal' with custom line width, direction and axis of the effect.

What's more, the FX can be stacked up. You could add, for example, a Barrel followed by a Blur and then topped-off with a Circle effect. Just by adjusting the ordering you can achieve some incredible and unique effects, very quickly.

We've worked hard to make the API as easy to use as possible, too. No more messing with pipelines or importing plugins. You can simply do:

```js const player = this.add.sprite(x, y, texture);

player.preFX.addGlow(0xff0000, 32); ```

This will add a 32 pixel red glow around the player Sprite.

Each effect returns a new FX Controller instance, allowing you to easily adjust the special effects in real-time via your own code, tweens and similar:

```js const fx = container.postFX.addWipe();

this.tweens.add({ targets: fx, progress: 1 }); ```

This will add a Wipe Effect to a Container instance and then tween its progress value from 0 to 1, causing the wipe to play out.

All texture-based Game Objects have access to Pre FX (so that includes Images, Sprites, TileSprites, Text, RenderTexture and Video). However, all Game Objects have access to Post FX, as do cameras. The difference is just when the effect is applied. For a 'pre' effect, it is applied before the Game Object is drawn. For a 'post' effect, it's applied after it has been drawn. All of the same effects are available to both.

js this.cameras.main.postFX.addTiltShift();

For example, this will apply a Tilt Shift effect to everything being rendered by the Camera. Which is a much faster way of doing it than applying the same effect to every child in a Scene. You can also apply them to Containers, allowing more fine-grained control over the display.

The full list of new methods are as follows:

Available only to texture-based Game Objects:

  • GameObject.preFX.addGlow adds a Glow Pre FX effect to the Game Object.
  • GameObject.preFX.addShadow adds a Shadow Pre FX effect to the Game Object.
  • GameObject.preFX.addPixelate adds a Pixelate Pre FX effect to the Game Object.
  • GameObject.preFX.addVignette adds a Vignette Pre FX effect to the Game Object.
  • GameObject.preFX.addShine adds a Shine Pre FX effect to the Game Object.
  • GameObject.preFX.addBlur adds a Blur Pre FX effect to the Game Object.
  • GameObject.preFX.addGradient adds a Gradient Pre FX effect to the Game Object.
  • GameObject.preFX.addBloom adds a Bloom Pre FX effect to the Game Object.
  • GameObject.preFX.addColorMatrix adds a ColorMatrix Pre FX effect to the Game Object.
  • GameObject.preFX.addCircle adds a Circle Pre FX effect to the Game Object.
  • GameObject.preFX.addBarrel adds a Barrel Pre FX effect to the Game Object.
  • GameObject.preFX.addDisplacement adds a Displacement Pre FX effect to the Game Object.
  • GameObject.preFX.addWipe adds a Wipe Pre FX effect to the Game Object.
  • GameObject.preFX.addReveal adds a Reveal Pre FX effect to the Game Object.
  • GameObject.preFX.addBokeh adds a Bokeh Pre FX effect to the Game Object.
  • GameObject.preFX.addTiltShift adds a TiltShift Pre FX effect to the Game Object.

Available to all Game Objects:

  • GameObject.postFX.addGlow adds a Glow Post FX effect to the Game Object.
  • GameObject.postFX.addShadow adds a Shadow Post FX effect to the Game Object.
  • GameObject.postFX.addPixelate adds a Pixelate Post FX effect to the Game Object.
  • GameObject.postFX.addVignette adds a Vignette Post FX effect to the Game Object.
  • GameObject.postFX.addShine adds a Shine Post FX effect to the Game Object.
  • GameObject.postFX.addBlur adds a Blur Post FX effect to the Game Object.
  • GameObject.postFX.addGradient adds a Gradient Post FX effect to the Game Object.
  • GameObject.postFX.addBloom adds a Bloom Post FX effect to the Game Object.
  • GameObject.postFX.addColorMatrix adds a ColorMatrix Post FX effect to the Game Object.
  • GameObject.postFX.addCircle adds a Circle Post FX effect to the Game Object.
  • GameObject.postFX.addBarrel adds a Barrel Post FX effect to the Game Object.
  • GameObject.postFX.addDisplacement adds a Displacement Post FX effect to the Game Object.
  • GameObject.postFX.addWipe adds a Wipe Post FX effect to the Game Object.
  • GameObject.postFX.addReveal adds a Reveal Post FX effect to the Game Object.
  • GameObject.postFX.addBokeh adds a Bokeh Post FX effect to the Game Object.
  • GameObject.postFX.addTiltShift adds a TiltShift Post FX effect to the Game Object.

New Features - Spatial Sound

Thanks to a contribution from @alxwest the Web Audio Sound system now supports spatial sound.

TODO - List all of the new properties and methods!

New Features - Spine 4 Support

Thanks to a contribution from @justintien we now have a Spine 4 Plugin available.

You can find it in the plugins/spine4.1 folder in the main repository. There are also a bunch of new npm scripts to help build this plugin:

npm run plugin.spine4.1.full.dist - To build new dist files for both canvas and WebGL. npm run plugin.spine4.1.dist - To build new dist files. npm run plugin.spine4.1.watch - To enter watch mode when doing dev work on the plugin. npm run plugin.spine4.1.runtimes - To build new versions of the Spine 4 runtimes.

The core plugin API remains largely the same. You can find lots of updated examples in the Phaser 3 Examples repo in the 3.60/spine4.1 folder.

We will maintain both the Spine 3 and 4 plugins for the forseeable future.

Additional Spine 3 Bug Fixes

  • Using drawDebug on a Spine Game Object to view its skeleton would cause the next object in the display list to be skipped for rendering, if it wasn't a Spine Game Object too. This is because the Spine 3 skeleton debug draw ends the spine batch but the Scene Renderer wasn't rebound. Fix #6380 (thanks @spayton)
  • The Spine Plugin add and make functions didn't clear and rebind the WebGL pipeline. This could cause two different visual issues: The first is that a Phaser Game Object (such as a Sprite) could be seen to change its texture to display the Spine atlas texture instead for a single frame, and then on the next pass revert back to normal again. The second issue is that if the Spine skeleton wasn't added to the display list, but just created (via addToScene: false) then the Sprite would take on the texture frame entirely from that point on. Fix #6362 (thanks @frissonlabs)
  • Previously, it wasn't possible for multiple Spine Atlases to use PNGs with the exact same filename, even if they were in different folders. The SpineFile loader has now been updated so that the always-unique Spine key is pre-pended to the filename, for example if the key was bonus and the PNG in the atlas was coin.png then the final key (as stored in the Texture Manager) is now bonus:coin.png. The SpinePlugin.getAtlasCanvas and getAtlasWebGL methods have been updated to reflect this change. Fix #6022 (thanks @orjandh)
  • If a SpineContainer had a mask applied to it and the next immediate item on the display list was another Spine object (outside of the Container) then it would fail to rebind the WebGL pipeline, causing the mask to break. It will now rebind the renderer at the end of the SpineContainer batch, no matter what, if it has a mask. Fix #5627 (thanks @FloodGames)

New Features - Plane Game Object

Phaser v3.60 contains a new native Plane Game Object. The Plane Game Object is a helper class that takes the Mesh Game Object and extends it, allowing for fast and easy creation of Planes. A Plane is a one-sided grid of cells, where you specify the number of cells in each dimension. The Plane can have a texture that is either repeated (tiled) across each cell, or applied to the full Plane.

The Plane can then be manipulated in 3D space, with rotation across all 3 axis.

This allows you to create effects not possible with regular Sprites, such as perspective distortion. You can also adjust the vertices on a per-vertex basis. Plane data becomes part of the WebGL batch, just like standard Sprites, so doesn't introduce any additional shader overhead. Because the Plane just generates vertices into the WebGL batch, like any other Sprite, you can use all of the common Game Object components on a Plane too, such as a custom pipeline, mask, blend mode or texture.

You can use the uvScroll and uvScale methods to adjust the placement and scaling of the texture if this Plane is using a single texture, and not a frame from a texture atlas or sprite sheet.

The Plane Game Object also has the Animation component, allowing you to play animations across the Plane just as you would with a Sprite.

While a Plane cannot be enabled for input it does have the methods hasFaceAt and getFaceAt which can be used with Pointer coordinates to detect if they have clicked on Plane face, or not.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Nine Slice Game Object

Phaser v3.60 contains a new native Nine Slice Game Object. A Nine Slice Game Object allows you to display a texture-based object that can be stretched both horizontally and vertically, but that retains fixed-sized corners. The dimensions of the corners are set via the parameters to the class. When you resize a Nine Slice Game Object only the middle sections of the texture stretch. This is extremely useful for UI and button-like elements, where you need them to expand to accommodate the content without distorting the texture.

The texture you provide for this Game Object should be based on the following layout structure:

A B +---+----------------------+---+ C | 1 | 2 | 3 | +---+----------------------+---+ | | | | | 4 | 5 | 6 | | | | | +---+----------------------+---+ D | 7 | 8 | 9 | +---+----------------------+---+

When changing this objects width and / or height:

areas 1, 3, 7 and 9 (the corners) will remain unscaled
areas 2 and 8 will be stretched horizontally only
areas 4 and 6 will be stretched vertically only
area 5 will be stretched both horizontally and vertically

You can also create a 3 slice Game Object:

This works in a similar way, except you can only stretch it horizontally. Therefore, it requires less configuration:

A B +---+----------------------+---+ | | | | C | 1 | 2 | 3 | | | | | +---+----------------------+---+

When changing this objects width (you cannot change its height)

areas 1 and 3 will remain unscaled
area 2 will be stretched horizontally

The above configuration concept is adapted from the Pixi NineSlicePlane.

To specify a 3 slice object instead of a 9 slice you should only provide the leftWidth and rightWidth parameters. To create a 9 slice you must supply all parameters.

The minimum width this Game Object can be is the total of leftWidth + rightWidth. 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 scale it.

In terms of performance, using a 3 slice Game Object is the equivalent of having 3 Sprites in a row. Using a 9 slice Game Object is the equivalent of having 9 Sprites in a row. The vertices of this object are all batched together and can co-exist with other Sprites and graphics on the display list, without incurring any additional overhead.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Pre FX Pipeline

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isPreFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Pre FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all PreFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Pre FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.
  • The WebGLPipeline.setTime method has a new optional parameter shader, which allows you to control the shader on which the time value is set.
  • If you add #define SHADER_NAME to the start of your shader then it will be picked up as the WebGLShader name during the setShadersFromConfig process within WebGLPipeline.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Updated Particle System

The Particle system has been mostly rewritten to give it a much needed overhaul. This makes the API cleaner, the Game Objects a lot more memory efficient and also introduces several great new features. In order to do this, we had to make some breaking changes. The largest being the way in which particles are now created.

Previously when you used the this.add.particles command it would create a ParticleEmitterManager instance. You would then use this to create an Emitter, which would actually emit the particles. While this worked and did allow a Manager to control multiple emitters we found that in discussion developers seldom used this feature and it was common for a Manager to own just one single Emitter.

In order to streamline memory and the display list we have removed the ParticleEmitterManager entirely. When you call this.add.particles you're now creating a ParticleEmitter instance, which is being added directly to the display list and can be manipulated just like any other Game Object, i.e. scaled, rotated, positioned, added to a Container, etc. It now extends the GameObject base class, meaning it's also an event emitter, which allowed us to create some handy new events for particles.

So, to create an emitter, you now give it an xy coordinate, a texture and an emitter configuration object (you can also set this later, but most commonly you'd do it on creation). I.e.:

js const emitter = this.add.particles(100, 300, 'flares', { frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

This will create a 'red flare' emitter at 100 x 300.

Prior to 3.60 it would have looked like:

```js const manager = this.add.particles('flares');

const emitter = manager.createEmitter({ x: 100, y: 300, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 }); ```

The change is quite subtle but makes a big difference internally.

The biggest real change is with the particle x/y coordinates. It's important to understand that if you define x/y coordinates within the emitter configuration, they will be relative to those given in the add.particles call:

js const emitter = this.add.particles(100, 300, 'flares', { x: 100, y: 100, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

In the above example the particles will emit from 200 x 400 in world space, because the emitter is at 100 x 300 and the particles emit from an offset of 100 x 100.

By making this change it now means you're able to do things like tween the x/y coordinates of the emitter (something you couldn't do before), or add a single emitter to a Container.

Other new features include:

Animated Particles

The Particle class now has an instance of the Animation State component within it. This allows a particle to play an animation when it is emitted, simply by defining it in the emitter config.

For example, this will make each particle play the 'Prism' animation on emission:

js const emitter = this.add.particles(400, 300, 'gems', { anim: 'prism' ... });

You can also allow it to select a random animation by providing an array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: [ 'prism', 'square', 'ruby', 'square' ] ... });

You've also the ability to cycle through the animations in order, so each new particle gets the next animation in the array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'square', 'ruby', 'square' ], cycle: true } ... });

Or even set a quantity. For example, this will emit 10 'prism' particles, then 10 'ruby' particles and then repeat:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'ruby' ], cycle: true, quantity: 10 } ... });

The Animations must have already been created in the Global Animation Manager and must use the same texture as the one bound to the Particle Emitter. Aside from this, you can still control them in the same way as any other particle - scaling, tinting, rotation, alpha, lifespan, etc.

Fast Forward Particle Time

  • You can now 'fast forward' a Particle Emitter. This can be done via either the emitter config, using the new advance property, or by calling the new ParticleEmitter.fastForward method. If, for example, you have an emitter that takes a few seconds to 'warm up' and get all the particles into position, this allows you to 'fast forward' the emitter to a given point in time. The value is given in ms. All standard emitter events and callbacks are still handled, but no rendering takes place during the fast-forward until it has completed.
  • The ParticleEmitter.start method has a new optional parameter advance that allows you to fast-forward the given amount of ms before the emitter starts flowing.

Particle Interpolation

  • It's now possible to create a new Interpolation EmitterOp. You do this by providing an array of values to interpolate between, along with the function name:

js const emitter = this.add.particles(0, 0, 'texture', { x: { values: [ 50, 500, 200, 800 ], interpolation: 'catmull' } ... });

This will interpolate the x property of each particle through the data set given, using a catmull rom interpolation function. You can also use linear or bezier functions. Interpolation can be combined with an ease type, which controls the progression through the time value. The related EmitterOpInterpolationConfig types have also been added.

Particle Emitter Duration

  • The Particle Emitter config has a new optional parameter duration:

js const emitter = this.add.particles(0, 0, 'texture', { speed: 24, lifespan: 1500, duration: 500 });

This parameter is used for 'flow' emitters only and controls how many milliseconds the emitter will run for before automatically turning itself off.

  • ParticleEmitter.duration is a new property that contains the duration that the Emitter will emit particles for in flow mode.
  • The ParticleEmitter.start method has a new optional parameter duration, which allows you to set the emitter duration when you call this method. If you do this, it will override any value set in the emitter configuration.
  • The ParticleEmitter.stop method has a new optional parameter kill. If set it will kill all alive particles immediately, rather than leaving them to die after their lifespan expires.

Stop After a set number of Particles

  • The Particle Emitter config has a new optional stopAfter property. This, combined with the frequency property allows you to control exactly how many particles are emitted before the emitter then stops:

js const emitter = this.add.particles(0, 0, 'texture', { x: { start: 400, end: 0 }, y: { start: 300, end: 0 }, lifespan: 3000, frequency: 250, stopAfter: 6, quantity: 1 });

In the above code the emitter will launch 1 particle (set by the quantity property) every 250 ms (set by the frequency property) and move it to xy 0x0. Once it has fired 6 particles (the stopAfter property) the emitter will stop and emit the COMPLETE event.

  • The stopAfter counter is reset each time you call the start or flow methods.

Particle Hold

  • You can configure a Particle to be frozen or 'held in place' after it has finished its lifespan for a set number of ms via the new hold configuration option:

js const emitter = this.add.particles(0, 0, 'texture', { lifespan: 2000, scale: { start: 0, end: 1 }, hold: 1000 ... });

The above will scale a Particle in from 0 to 1 over the course of its lifespan (2 seconds). It will then hold it on-screen for another second (1000 ms) before the Emitter recycles it and removes it from display.

Particle Emitter Events

  • The Particle Emitter will now fire 5 new events. Listen for the events as follows:

```js const emitter = this.add.particles(0, 0, 'flares');

emitter.on('start', (emitter) => { // emission started });

emitter.on('explode', (emitter, particle) => { // emitter 'explode' called });

emitter.on('deathzone', (emitter, particle, deathzone) => { // emitter 'death zone' called });

emitter.on('stop', (emitter) => { // emission has stopped });

emitter.on('complete', (emitter) => { // all particles fully dead }); ```

  • The Particles.Events.START event is fired whenever the Emitter begins emission of particles in flow mode. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.EXPLODE event is fired whenever the Emitter explodes a bunch of particles via the explode method. A reference to the ParticleEmitter and a reference to the most recently fired Particle instance are the two parameters.
  • The Particles.Events.DEATH_ZONE event is fired whenever a Particle is killed by a Death Zone. A reference to the ParticleEmitter, the killed Particle and the DeathZone that caused it are the 3 parameters.
  • The Particles.Events.STOP event is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call the stop method, or when an Emitter hits its duration or stopAfter limit. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.COMPLETE event is fired when the final alive particle expires.

Multiple Emit Zones

  • In v3.60 a Particle Emitter can now have multiple emission zones. Previously, an Emitter could have only a single emission zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addEmitZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addEmitZone({ type: 'edge', source: circle, quantity: 64 }); ```

  • When an Emitter has more than one emission zone, the Particles will cycle through the zones in sequence. For example, an Emitter with 3 zones would emit its first particle from zone 1, the second from zone 2, the third from zone 3, the fourth from zone 1, etc.
  • You can control how many particles are emitted from a single zone via the new total property. EdgeZone.total and RandomZone.total are new properties that control the total number of particles the zone will emit, before passing control over to the next zone in the list, if any. The default is -1.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeEmitZone is a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getEmitZone is a new method that Particles call when they are 'fired' in order to set their starting position, if any.
  • The property ParticleEmitter.emitZone has been removed. It has been replaced with the new ParticleEmitter.emitZones array-based property.

Multiple Death Zones

  • In v3.60 a Particle Emitter can now have multiple death zones. Previously, an Emitter could have only a single death zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addDeathZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addDeathZone({ type: 'onEnter', source: circle }); ```

  • When an Emitter has more than one Death Zone, the Particles will check themselves against all of the Death Zones, to see if any of them kills them.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeDeathZone is a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getDeathZone is a new method that Particles call when they are updated in order to check if they intersect with any of the Death Zones.
  • The property ParticleEmitter.deathZone has been removed. It has been replaced with the new ParticleEmitter.deathZones array-based property.

Particle Colors

  • You can now specify a new color property in the Emitter configuration. This takes the form of an array of hex color values that the particles will linearly interpolate between during theif lifetime. This allows you to now change the color of a particle from birth to death, which gives you far more control over your emitter visuals than ever before. You'd use it as follows:

js const flame = this.add.particles(150, 550, 'flares', { frame: 'white', color: [ 0xfacc22, 0xf89800, 0xf83600, 0x9f0404 ], colorEase: 'quad.out', lifespan: 2400, angle: { min: -100, max: -80 }, scale: { start: 0.70, end: 0, ease: 'sine.out' }, speed: 100, advance: 2000, blendMode: 'ADD' });

Here you can see the array of 4 colors it will interpolate through.

  • The new colorEase configuration property allows you to define the ease used to calculate the route through the interpolation. This can be set to any valid ease string, such as sine.out or quad.in, etc. If left undefined it will use linear as default.
  • EmitterColorOp is a brand new Emitter Op class that specifically controls the handling of color values, it extends EmitterOp and uses the same methods but configured for faster color interpolation.
  • If you define color in your config it will override any Emitter tint values you may have set. In short, use color if you wish to adjust the color of the particles during their lifespan and use tint if you wish to modify either the entire emitter at once, or the color of the particles on birth only.
  • ParticleEmitter.particleColor is a new property that allows you to get and set the particle color op value.
  • ParticleEmitter.colorEase is a new property that allows you to get and set the ease function used by the color op.

Particle Sort Order

  • You now have much more control over the sorting order of particles in an Emitter. You can set the new ParticleEmitter.sortProperty and sortOrderAsc properties to set how (and if) particles should be sorted prior to rendering. For example, setting sortProperty to y would mean that the particles will be sorted based on their y value prior to rendering. The sort order controls the order in which the particles are rendered. For example:

```js const emitter = this.add.particles(100, 300, 'blocks', { frame: 'redmonster', lifespan: 5000, angle: { min: -30, max: 30 }, speed: 150, frequency: 200 });

emitter.setSortProperty('y', true); ```

  • The new ParticleEmitter.setSortProperty method allows you to modify the sort property and order at run-time.
  • The new ParticleEmitter.setSortCallback method allows you to set a callback that will be invoked in order to sort the particles, rather than using the built-in one. This gives you complete freedom over the logic applied to particle render sorting.

Particle Bounds, Renderer Culling and Overlap

  • Particles now have the ability to calculate their bounding box, based on their position, scale, rotation, texture frame and the transform of their parent. You can call the new Particle.getBounds method to return the bounds, which also gets stored in the new Particle.bounds Rectangle property.
  • ParticleEmitter.getBounds is a new method that will return the bounds of the Emitter based on all currently active particles. Optional parameters allow you to pad out the bounds and/or advance time in the particle flow, to allow for a more accurate overall bounds generation.
  • ParticleEmitter.viewBounds is a new property that is a Geom Rectangle. Set this Rectangle to define the overall area the emitter will render to. If this area doesn't intersect with the Camera then the emitter will be culled from rendering. This allows you to populate large Scenes with active emitters that don't consume rendering resources even though they are offscreen. Use the new getBounds method to help define the viewBounds area.
  • ParticleEmitter.overlap is a new method that will run a rectangle intersection test against the given target and all alive particles, returning those that overlap in an array. The target can be a Rectangle Geometry object or an Arcade Physics Body.
  • Particle.kill is a new method that will set the life of the particle to zero, forcing it to be immediately killed on the next Particle Emitter update.
  • ParticleEmitter.getWorldTransformMatrix is a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.
  • ParticleEmitter.worldMatrix is a new property that holds a TransformMatrix used for bounds calculations.

Particle Emitter Bounds

  • Prior to v3.60 a Particle Emitter had a bounds property. This was a Rectangle and if a Particle hit any of its edges it would rebound off it based on the Particles bounce value. In v3.60 this action has been moved to a Particle Processor. You can still configure the bounds via the Emitter config using the bounds property, as before. And you can configure which faces collide via the collideLeft etc properties. However, the following internal changes have taken place:
  • ParticleBounds is a new Particle Processor class that handles updating the particles.
  • The ParticleEmitter.setBounds method has been replaced with ParticleEmitter.addParticleBounds which now returns a new ParticleBounds Particle Processor instance.
  • The ParticleEmitter.bounds property has been removed. Please see the addParticleBounds method if you wish to retain this object.
  • The ParticleEmitter.collideLeft property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideRight property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideTop property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The ParticleEmitter.collideBottom property has been removed. It's now part of the ParticleBounds Particle Processor.
  • The Particle.checkBounds method has been removed as it's now handled by the Particle Processors.

Particle Processors

  • ParticleProcessor is a new base class that you can use to create your own Particle Processors, which are special processors capable of manipulating the path of Particles based on your own logic or math. It provides the structure required to handle the processing of particles and should be used as a base for your own classes.
  • GravityWell now extends the new ParticleProcessor class.
  • ParticleEmitter.addParticleProcessor is a new method that allows you to add a Particle Processor instance to the Emitter. The old createGravityWell method now uses this.
  • ParticleEmitter.removeParticleProcessor is a new method that will remove a Particle Processor from an Emitter.
  • ParticleEmitter.processors is a new List property that contains all of the Particle Processors belonging to the Emitter.
  • The ParticleEmitter.wells property has been removed. You should now use the new processors property instead, they are functionally identical.
  • ParticleProcessor.update is the method that handles all of the particle manipulation. It now has a new 4th parameter t that is the normalized lifespan of the Particle being processed.

Particle System EmitterOp Breaking Changes and Updates:

All of the following properties have been replaced on the ParticleEmitter class. Previously they were EmitterOp instances. They are now public getter / setters, so calling, for example, emitter.particleX will now return a numeric value - whereas before it would return the EmitterOp instance. This gives developers a lot more freedom when using Particle Emitters. Before v3.60 it was impossible to do this, for example:

js this.tweens.add({ targets: emitter, particleX: 400 });

I.e. you couldn't tween an emitters particle spawn position by directly accessing its x and y properties. However, now that all EmitterOps are getters, you're free to do this, allowing you to be much more creative and giving a nice quality-of-life improvement.

If, however, your code used to access EmitterOps, you'll need to change it as follows:

```js // Phaser 3.55 emitter.x.onChange(value) // Phaser 3.60 emitter.particleX = value

// Phaser 3.55 let x = emitter.x.propertyValue // Phaser 3.60 let x = emitter.particleX

// Phaser 3.55 emitter.x.onEmit() emitter.x.onUpdate() // Phaser 3.60 emitter.ops.x.onEmit() emitter.ops.x.onUpdate() ```

All of following EmitterOp functions can now be found in the new ParticleEmitter.ops property and have been replaced with getters:

  • accelerationX
  • accelerationY
  • alpha
  • angle
  • bounce
  • color
  • delay
  • lifespan
  • maxVelocityX
  • maxVelocityY
  • moveToX
  • moveToY
  • quantity
  • rotate
  • scaleX
  • scaleY
  • speedX
  • speedY
  • tint
  • x
  • y

Which means you can now directly access, modify and tween any of the above emitter properties at run-time while the emitter is active.

Another potentially breaking change is the removal of two internal private counters. These should never have been used directly anyway, but they are:

  • ParticleEmitter._counter - Now available via ParticleEmitter.flowCounter
  • ParticleEmitter._frameCounter - Now available via ParticleEmitter.frameCounter
  • EmitterOp._onEmit is a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyEmit method, to ensure that the Emitter current property remains current.
  • EmitterOp._onUpdate is a new private reference to the update callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyUpdate method, to ensure that the Emitter current property remains current.
  • EmitterOp.destroy is a new method that nulls all references. This is called automatically when a ParticleEmitter is itself destroyed.

Further Particle System Updates and Fixes:

  • The Particle DeathZone.willKill method now takes a Particle instance as its only parameter, instead of x and y coordinates, allowing you to perform more complex checks before deciding if the Particle should be killed, or not.
  • The Particle.resetPosition method has been renamed to setPosition and it now takes optional x/y parameters. If not given, it performs the same task as resetPosition did in earlier versions.
  • The ParticleEmitter class now has the AlphaSingle Component. This allows you to call setAlpha on the Emitter instance itself and have it impact all particles being rendered by it, allowing you to now 'fade in/out' a whole Emitter.
  • Setting frequency wasn't working correctly in earlier versions. It should allow you to specify a time, in ms, between which each 'quantity' of particles is emitted. However, the preUpdate loop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles.
  • Calling ParticleEmitter.start wouldn't reset the _frameCounter value internally, meaning the new emission didn't restart from the first texture frame again.
  • ParticleEmitter.counters is a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous _counter and _frameCounter properties have been merged into this array, along with new ones required for new features.
  • The WebGL Renderer will now use the new setQuad feature of the Transform Matrix. This vastly reduces the amount of math and function calls per particle, from 8 down to 1, increasing performance.
  • Particles with a scaleX or scaleY value of zero will no longer be rendered.
  • ParticleEmitter.preDestroy is a new method that will now clean-up all resources and internal arrays and destroy all Particles that the Emitter owns and clean-up all external references.
  • Particle.destroy is a new method that will clean up all external references and destroy the Animation State controller.
  • The ParticleEmitter._frameLength property is now specified on the class, rather than added dynamically at run-time, helping preserve class shape.
  • The ParticleEmitter.defaultFrame property has been removed as it's not required.
  • Calling ParticleEmitter.setFrame no longer resets the internal _frameCounter value to zero. Instead, the counter comparison has been hardened to >= instead of === to allow this value to change mid-emission and never reach the total.
  • The ParticleEmitter.configFastMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • The ParticleEmitter.configOpMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • Particle.scene is a new property that references the Scene the Particle Emitter belongs to.
  • Particle.anims is a new property that is an instance of the AnimationState component.
  • Particle.emit is a new proxy method that passes all Animation related events through to the Particle Emitter Manager to emit, as Particles cannot emit events directly.
  • Particle.isCropped is a new read-only property. Do not modify.
  • Particle.setSizeToFrame is a new internal NOOP method. Do not call.
  • ParticleEmitter.anims is a new property that contains the Animation keys that can be assigned to Particles.
  • ParticleEmitter.currentAnim is a new property that contains the index of the current animation, as tracked in cycle playback.
  • ParticleEmitter.randomAnim is a new boolean property that controls if the animations are selected randomly, or in a cycle.
  • ParticleEmitter.animQuantity is a new property that controls the number of consecutive particles that are emitted with the current animation.
  • ParticleEmitter.counters is a new internal Float32Array that holds all the counters the Emitter uses.
  • ParticleEmitter.getAnim is a new method, called by Particles when they are emitted, that will return the animation to use, if any.
  • ParticleEmitter.setAnim is a new method, called with the Emitter Manager, that sets the animation data into the Emitter.
  • The Particles.EmitterOp.toJSON method will now JSON stringify the property value before returning it.
  • Particles.EmitterOp.method is a new property that holds the current operation method being used. This is a read-only numeric value.
  • Particles.EmitterOp.active is a new boolean property that defines if the operator is alive, or not. This is now used by the Emitter instead of nulling Emitter properties, helping maintain class shape.
  • Particles.EmitterOp.getMethod is a new internal method that returns the operation function being used as a numeric value. This is then cached in the method property.
  • The Particles.EmitterOp.setMethods method has been updated so it now has a non-optional 'method' parameter. It has also been rewritten to be much more efficient, now being just a single simple select/case block.
  • The Particles.EmitterOp.onChange method will now use the cached 'method' property to avoid running through the setMethods function if not required, allowing each Particle EmitterOp to skip a huge chunk of code.
  • We've also greatly improved the documentation around the Particle classes.
  • ParticleEmitter.setConfig is a new method that allows you to set the configuration of the Emitter. Previously this was known as fromJSON.
  • The ParticleEmitter.setPosition method no longer changes the position of the particle emission point, but of the Emitter itself.
  • The ParticleEmitter.setBounds method has been renamed to setParticleBounds.
  • The ParticleEmitter.setSpeed method has been renamed to setParticleSpeed.
  • The ParticleEmitter.setScale method has been renamed to setParticleScale as setScale will now set the scale of the whole Emitter.
  • The ParticleEmitter.setScaleX and setScaleY methods have been removed. Please use setParticleScale.
  • The ParticleEmitter.setGravity method has been renamed to setParticleGravity.
  • The ParticleEmitter.setGravityX and setGravityY methods have been removed. Please use setParticleGravity.
  • The ParticleEmitter.setAlpha method has been renamed to setParticleAlpha as setAlpha will now set the alpha of the whole Emitter.
  • The ParticleEmitter.setTint method has been renamed to setParticleTint.
  • The ParticleEmitter.setLifespan method has been renamed to setParticleLifespan.
  • The ParticleEmitter.on property has been renamed to emitting to avoid conflicts with the Event Emitter.
  • The ParticleEmitter.x property has been renamed to particleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.y property has been renamed to particleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleX property has been renamed to particleScaleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleY property has been renamed to particleScaleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.tint property has been renamed to particleTint and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.alpha property has been renamed to particleAlpha and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.angle property has been renamed to particleAngle and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.rotate property has been renamed to particleRotate and is a new EmitterOp capable of being tweened.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

TODO

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

  • The RenderTarget class will now create a Framebuffer that includes a Depth Stencil Buffer attachment by default. Previously, it didn't. By attaching a stencil buffer it allows things like Geometry Masks to work in combination with Post FX and other Pipelines. Fix #5802 (thanks @mijinc0)
  • When calling PipelineManager.clear and rebind it will now check if the vao extension is available, and if so, it'll bind a null vertex array. This helps clean-up from 3rd party libs that don't do this directly, such as ThreeJS.
  • The mipmapFilter property in the Game Config now defaults to '' (an empty string) instead of 'LINEAR'. The WebGLRenderer has been updated so that it will no longer create mipmaps at all with a default config. This potential saves a lot of VRAM (if your game has a lot of power-of-two textures) where before it was creating mipmaps that may never have been used. However, you may notice scaling doesn't look as crisp as it did before if you were using this feature without knowing it. To get it back, just add mipmapFilter: 'LINEAR' to your game config. Remember, as this is WebGL1 it only works with power-of-two sized textures.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • The batchLine method in the Multi Pipeline will now check to see if the dxdy len is zero, and if so, it will abort drawing the line. This fixes issues on older Android devices, such as the Samsung Galaxy S6 or Kindle 7, where it would draw erroneous lines leading up to the top-left of the canvas under WebGL when rendering a stroked rounded rectangle. Fix #5429 (thanks @fkoch-tgm @sreadixl)
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light fragment shader will now use the outTintEffect attribute meaning the Light Pipeline will now correctly light both tinted and fill-tinted Game Objects. Fix #5452 (thanks @kainage)
  • The Light Pipeline will now check to see if a Light2D enabled Game Object has a parent Container, or not, and factor the rotation and scale of this into the light calculation. Fix #6086 (thanks @irongaze)
  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been rewritten to help with performance, resolve some of its lingering issues and unifies the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • The Tween.seek method used to take a value between 0 and 1, based on how far through the Tween you wished to seek. However, it did not work with infinitely looping or repeating Tweens and would crash the browser tab. The new seek method takes a value in milliseconds instead and works perfectly on infinite Tweens.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as the source for a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • origin is now (0.5, 0.5) by default instead of (0, 0).

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Post Pipeline Updates

In order to add clarity in the codebase we have created a new PostPipeline Component and moved all of the relevant functions from the Pipeline component in to it. This leads to the following changes:

  • PostPipeline is a new Game Object Component that is now inherited by all Game Objects that are capable of using it.
  • Game Objects with the PostPipeline component now have a new property called postPipelineData. This object is used for storing Post Pipeline specific data in. Previously, both regular and post pipelines used the same pipelineData object, but this has now been split up for flexibility.
  • The Pipeline.resetPipeline method no longer has its first resetPostPipelines argument. It now has just one argument resetData so please be aware of this if you call this function anywhere in your code.
  • PostPipeline.initPostPipeline is a new method that should be called by any Game Object that supports Post Pipelines.
  • The following Game Objects now have the new PostPipeline Component exclusively: Container and Layer.

Input System Updates

There are breaking changes from previous versions of Phaser.

  • The InteractiveObject.alwaysEnabled property has been removed. It is no longer checked within the InputPlugin and setting it will have no effect. This property has not worked correctly since version 3.52 when the new render list was implemented. Upon further investigation we decided to remove the property entirely, rather than shoe-horn it into the render list. If you need to create a non-rendering Interactive area, use the Zone Game Object instead.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.
  • The GameObjects.Components.Mask.createBitmapMask method can now accept the x, y, texture and frame parameters new to the BitmapMask constructor.
  • Previously, calling createBitmapMask on a Shape Game Object would fail unless you passed the shape to the method. Now, it will correctly create a mask from the Shape without needing to pass it. Fix #5976 (thanks @samme)

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • The Graphics.strokeRoundedRect and fillRoundedRect methods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow)
  • AnimationManager.getAnimsFromTexture is a new method that will return all global Animations, as stored in the Animation Manager, that have at least one frame using the given Texture. This will not include animations created directly on local Sprites.
  • BitmapText.setLineSpacing is a new method that allows you to set the vertical spacing between lines in multi-line BitmapText Game Objects. It works in the same was as spacing for Text objects and the spacing value can be positive or negative. See also BitmapText.lineSpacing for the property rather than the method.
  • WebGLPipeline.vertexAvailable is a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.
  • The Tilemap and TilemapLayer classes have a new method getTileCorners. This method will return an array of Vector2s with each entry corresponding to the corners of the requested tile, in world space. This currently works for Orthographic and Hexagonal tilemaps.
  • BaseSoundManager.getAllPlaying is a new method that will return all currently playing sounds in the Sound Manager.
  • Animation.showBeforeDelay is a new optional boolean property you can set when creating, or playing an animation. If the animation has a delay before playback starts this controls if it should still set the first frame immediately, or after the delay has expired (the default).
  • InputPlugin.resetPointers is a new method that will loop through all of the Input Manager Pointer instances and reset them all. This is useful if a 3rd party component, such as Vue, has stolen input from Phaser and you need to reset its input state again.
  • Pointer.reset is a new method that will reset a Pointer instance back to its 'factory' settings.
  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • Game.isPaused is a new boolean that tracks if the Game loop is paused, or not (and can also be toggled directly)
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • The BaseCamera has had its Alpha component replaced with AlphaSingle. Previously you had access to properties such as alphaTopLeft that never worked, now it correctly has just a single alpha property (thanks @samme)
  • Time.Clock.startTime is a new property that stores the time the Clock (and therefore the Scene) was started. This can be useful for comparing against the current time to see how much real world time has elapsed (thanks @samme)
  • ColorMatrix._matrix and _data are now Float32Arrays.
  • Calling the ColorMatrix.set, reset and getData methods all now use the built-in Float32 Array operations, making them considerably faster.
  • ColorMatrix.BLACK_WHITE is a new constant used by blackwhite operations.
  • ColorMatrix.NEGATIVE is a new constant used by negative operations.
  • ColorMatrix.DESATURATE_LUMINANCE is a new constant used by desaturation operations.
  • ColorMatrix.SEPIA is a new constant used by sepia operations.
  • ColorMatrix.LSD is a new constant used by LSD operations.
  • ColorMatrix.BROWN is a new constant used by brown operations.
  • ColorMatrix.VINTAGE is a new constant used by vintage pinhole operations.
  • ColorMatrix.KODACHROME is a new constant used by kodachrome operations.
  • ColorMatrix.TECHNICOLOR is a new constant used by technicolor operations.
  • ColorMatrix.POLAROID is a new constant used by polaroid operations.
  • ColorMatrix.SHIFT_BGR is a new constant used by shift BGR operations.
  • If no Audio URLs match the given device a new warning is now displayed in the console (thanks @samme)
  • Texture.has will now return a strict boolean, rather than an object that can be cooerced into a boolean (thanks @samme)
  • The CanvasTexture.draw method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The CanvasTexture.drawFrame method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The CanvasTexture.clear method has a new optional parameter update which allows you to control if the internal ImageData is recalculated, or not (thanks @samme)
  • The Game.registry, which is a DataManager instance that can be used as a global store of game wide data will now use its own Event Emitter, instead of the Game's Event Emitter. This means it's perfectly safe for you to now use the Registry to emit and listen for your own custom events without conflicting with events the Phaser Game instance emits.
  • The GenerateVerts function has a new optional parameter flipUV which, if set, will flip the UV texture coordinates (thanks cedarcantab)
  • The GenerateVerts function no longer errors if the verts and uvs arrays are not the same size and containsZ is true (thanks cedarcantab)
  • The Device.Browser checks for Opera and Edge have been updated to use the more modern user agent strings those browsers now use. This breaks compatibility with really old versions of those browsers but fixes it for modern ones (which is more important) (thanks @ ArtemSiz)
  • The SceneManager.processQueue method will no longer return if a new Scene was added, after starting it. This allows any other queued operations to still be run in the same frame, rather than being delayed until the next game frame. Fix #5359 (thanks @telinc1)
  • Camera.scrollX and scrollY will now only set the Camera.dirty flag to true if the new value given to them is different from their current value. This allows you to use this property in your own culling functions. Fix #6088 (thanks @Waclaw-I)
  • Face.update is a new method that updates each of the Face vertices. This is now called internally by Face.isInView.
  • Vertex.resize is a new method that will set the position and then translate the Vertex based on an identity matrix.
  • The Vertex.update method now returns this to allow it to be chained.
  • You can now optionally specify the maxSpeed value in the Arcade Physics Group config (thanks @samme)
  • You can now optionally specify the useDamping boolean in the Arcade Physics Group config (thanks @samme)
  • Removed the HexagonalTileToWorldY function as it cannot work without an X coordinate. Use HexagonalTileToWorldXY instead.
  • Removed the HexagonalWorldToTileY function as it cannot work without an X coordinate. Use HexagonalWorldToTileXY instead.
  • Earcut has been updated to version 2.2.4. This release improves performance by 10-15% and fixes 2 rare race conditions that could leave to infinite loops. Earcut is used internally by Graphics and Shape game objects when triangulating polygons for complex shapes.
  • The BaseSoundManager.getAll method used to require a key parameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned.
  • The WebAudioSoundManager will now detect if the Audio Context enters a 'suspended' or 'interrupted' state as part of its update loop and if so it'll try to resume the context. This can happen if you change or disable the audio device, such as plugging in headphones with built-in audio drivers then disconnecting them, or swapping tabs on iOS. Fix #5353 (thanks @helloyoucan)
  • The CONTEXT_RESTORED Game Event has been removed and the WebGL Renderer no longer listens for the contextrestored DOM event, or has a contextRestoredHandler method. This never actually worked properly, in any version of Phaser 3 - although the WebGLRenderer would be restored, none of the shaders, pipelines or textures were correctly re-created. If a context is now lost, Phaser will display an error in the console and all rendering will halt. It will no longer try to re-create the context, leading to masses of WebGL errors in the console. Instead, it will die gracefully and require a page reload.
  • The Text and TileSprite Game Objects no longer listen for the CONTEXT_RESTORED event and have had their onContextRestored methods removed.
  • Scenes.Systems.canInput is a new internal method that determines if a Scene can receive Input events, or not. This is now used by the InputPlugin instead of the previous isActive test. This allows a Scene to emit and handle input events even when it is running init or preload. Previously, it could only do this after create had finished running. Fix #6123 (thanks @yaasinhamidi)
  • The BitmapText Game Object has two new read-only properties displayWidth and displayHeight. This allows the BitmapText to correctly use the GetBounds component.
  • The BitmapText Game Object now has the GetBounds component added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames)
  • WebGLSnapshot will now flip the pixels in the created Image element if the source was a framebuffer. This means grabbing a snapshot from a Dynamic or Render Texture will now correctly invert the pixels on the y axis for an Image. Grabbing from the game renderer will skip this.
  • WebGLRenderer.snapshotFramebuffer and by extension, the snapshot methods in Dynamic Textures and Render Textures, has been updated to ensure that the width and height never exceed the framebuffer dimensions, or it'll cause a runtime error. The method snapshotArea has had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)
  • Animation.stop is always called when a new animation is loaded, regardless if the animation was playing or not and the delayCounter is reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)
  • ScaleManager.listeners has been renamed to domlisteners to avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)
  • Geom.Intersects.LineToLine will no longer create an internal Point object, as it's not required internally (thanks @Trissolo)
  • The tempZone used by GridAlign has now had setOrigin(0, 0) applied to it. This leads to more accurate / expected zone placement when aligning grid items.
  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • The Container.getBounds method will now use getTextBounds if one of its children is a BitmapText Game Object, giving more accurate bounds results (thanks @EmilSV)
  • The renderFlags property, used to determine if a Game Object will render, or not, would be calculated incorrectly depending on the order of the scaleX and scaleY properties. It now works regardless of the order (thanks @mizunokazumi)
  • The SpriteSheetFromAtlas parser was using the incorrect sourceIndex to grab frames from a given texture. This caused a crash whenever a trimmed spritesheet was added from any multiatlas image other than the first (thanks @Bambosh)
  • The maxSpeed setting in Arcade Physics wasn't recalculated during the Body update, prior to being compared, leading to inconsistent results. Fix #6329 (thanks @Bambosh)
  • Several paths have been fixed in the phaser-core.js entry point (thanks @pavle-goloskokovic)
  • When a Game Object had Input Debug Enabled the debug image would be incorrectly offset if the Game Object was attached to was scaled and the hit area shape was smaller, or offset, from the Game Object. Fix #4905 #6317 (thanks @PavelMishin @justinlueders)
  • An inactive Scene is no longer updated after a Scene transition completes. Previously, it will still update the Scene one final time. This fix also prevents the POST_UPDATE event from firing after the transition is over. Fix #5550 (thanks @mijinc0 @samme)
  • Although not recommended, when adding a Layer Game Object to another Layer Game Object, it will no longer error because it cannot find the removeFromDisplayList function. Fix #5595 (thanks @tringcooler)
  • The Actions.Spread method will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV)
  • Calling setDisplayOrigin on a Video Game Object would cause the origins to be set to NaN if the Video was created without an asset key. It will now give Videos a default size, preventing this error, which is reset once a video is loaded. Fix #5560 (thanks @mattjennings)
  • When ImageFile loads with a linked Normal Map and the map completes first, but the Image is still in a pending state, it would incorrectly add itself to the cache instead of waiting. It now checks this process more carefully. Fix #5886 (thanks @inmylo)
  • Using a dataKey to specify a part of a JSON file when using load.pack would fail as it wouldn't correctly assign the right part of the pack file to the Loader. You can now use this parameter properly. Fix #6001 (thanks @rexrainbow)
  • The Text.advancedWordWrap function would incorrectly merge the current and next lines when wrapping words with carriage-returns in. Fix #6187 (thanks @Ariorh1337 @robinheidrich)
  • Recoded the point conversion math in the HexagonalTileToWorldXY function as it was incorrect. Now returns world coordinates correctly.
  • Tilemap.copy would error if you copied a block of tiles over itself, even partially, as it tried to copy already replaced tiles as part of the function. It will now copy correctly, regardless of source or destination areas. Fix #6188 (thanks @Arkyris)
  • Tile.copy will now use the DeepCopy function to copy the Tile.properties object, as otherwise it just gets copied by reference.
  • Recoded the point conversion math in the HexagonalWorldToTileXY function as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich)
  • Fixed the point conversion math in the IsometricWorldToTileXY function and added optional boolean property that allows the setting of the tile origin to the top or base. Fix #5781 (thanks @benjamin-wilson)
  • Calling Tilemap.worldToTileX or worldToTileY on a Isometric or Hexagonal Tilemap will now always return null instead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should use worldToTileXY instead.
  • The Game.headlessStep method will now reset SceneManager.isProcessing before PRE_RENDER. This fixes issues in HEADLESS mode where the Scene Manager wouldn't process additionally added Scenes created after the Game had started. Fix #5872 #5974 (thanks @micsun-al @samme)
  • If Rope.setPoints was called with the exact same number of points as before, it wouldn't set the dirty flag, meaning the vertices were not updated on the next render (thanks @stupot)
  • Particle.fire will now check to see if the parent Emitter is set to follow a Game Object and if so, and if the x/y EmitterOps are spread ops, then it'll space the particles out based on the follower coordinates, instead of clumping them all together. Fix #5847 (thanks @sreadixl)
  • When using RTL (right-to-left) Text Game Objects, the Text would vanish on iOS15+ if you changed the text or font style. The context RTL properties are now restored when the text is updated, fixing this issue. Fix #6121 (thanks @liorGameDev)
  • The Tilemap.destroyLayer method would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme)
  • MapData and ObjectLayer will now enforce that the Tilemap.objects property is always an array. Sometimes Tiled willl set it to be a blank object in the JSON data. This fix makes sure it is always an array. Fix #6139 (thanks @robbeman)
  • The ParseJSONTiled function will now run a DeepCopy on the source Tiled JSON, which prevents object mutation, fixing an issue where Tiled Object Layer names would be duplicated if used across multiple Tilemap instances. Fix #6212 (thanks @temajm @wahur666)
  • The method Color.setFromHSV would not change the members h, s and v, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow)
  • When calling GameObject.getPostPipeline and passing in a string for the pipeline name it would error with 'Uncaught TypeError: Right-hand side of 'instanceof' is not an object'. This is now handled correctly internally (thanks @neki-dev)
  • When playing a chained animation, the nextAnim property could get set to undefined which would stop the next animation in the queue from being set. The check now handles all falsey cases. Fix #5852 (thanks @Pythux)
  • When calling InputPlugin.clear it will now call removeDebug on the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton)
  • The Video.loadURL method wouldn't load the video or emit the VIDEO_CREATED event unless noAudio was specified. A load event handler has been added to resolve this (thanks @samme)
  • If you create a repeating or looping TimerEvent with a delay of zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan)
  • The endFrame and startFrame properties of the SpriteSheet parser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the given startFrame so that is frame zero and end at endFrame, regardless how many other frames are in the sheet.
  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Re

- JavaScript
Published by photonstorm over 3 years ago

phaser - Phaser 3.60 Beta 18

Version 3.60.0 - Miku - in development

New Features - Nine Slice Game Object

Phaser 3.60 contains a new native Nine Slice Game Object. A Nine Slice Game Object allows you to display a texture-based object that can be stretched both horizontally and vertically, but that retains fixed-sized corners. The dimensions of the corners are set via the parameters to the class. When you resize a Nine Slice Game Object only the middle sections of the texture stretch. This is extremely useful for UI and button-like elements, where you need them to expand to accommodate the content without distorting the texture.

The texture you provide for this Game Object should be based on the following layout structure:

A B +---+----------------------+---+ C | 1 | 2 | 3 | +---+----------------------+---+ | | | | | 4 | 5 | 6 | | | | | +---+----------------------+---+ D | 7 | 8 | 9 | +---+----------------------+---+

When changing this objects width and / or height:

areas 1, 3, 7 and 9 (the corners) will remain unscaled
areas 2 and 8 will be stretched horizontally only
areas 4 and 6 will be stretched vertically only
area 5 will be stretched both horizontally and vertically

You can also create a 3 slice Game Object:

This works in a similar way, except you can only stretch it horizontally. Therefore, it requires less configuration:

A B +---+----------------------+---+ | | | | C | 1 | 2 | 3 | | | | | +---+----------------------+---+

When changing this objects width (you cannot change its height)

areas 1 and 3 will remain unscaled
area 2 will be stretched horizontally

The above configuration concept is adapted from the Pixi NineSlicePlane.

To specify a 3 slice object instead of a 9 slice you should only provide the leftWidth and rightWidth parameters. To create a 9 slice you must supply all parameters.

The minimum width this Game Object can be is the total of leftWidth + rightWidth. 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 scale it.

In terms of performance, using a 3 slice Game Object is the equivalent of having 3 Sprites in a row. Using a 9 slice Game Object is the equivalent of having 9 Sprites in a row. The vertices of this object are all batched together and can co-exist with other Sprites and graphics on the display list, without incurring any additional overhead.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Updated Particle System

The Particle system has been mostly rewritten to give it a much needed overhaul. This makes the API cleaner, the Game Objects a lot more memory efficient and also introduces several great new features. In order to do this, we had to make some breaking changes. The largest being the way in which particles are now created.

Previously when you used the this.add.particles command it would create a ParticleEmitterManager instance. You would then use this to create an Emitter, which would actually emit the particles. While this worked and did allow a Manager to control multiple emitters we found that in discussion developers seldom used this feature and it was common for a Manager to own just one single Emitter.

In order to streamline memory and the display list we have removed the ParticleEmitterManager entirely. When you call this.add.particles you're now creating a ParticleEmitter instance, which is being added directly to the display list and can be manipulated just like any other Game Object, i.e. scaled, rotated, positioned, added to a Container, etc. It now extends the GameObject base class, meaning it's also an event emitter, which allowed us to create some handy new events for particles.

So, to create an emitter, you now give it an xy coordinate, a texture and an emitter configuration object (you can also set this later, but most commonly you'd do it on creation). I.e.:

js const emitter = this.add.particles(100, 300, 'flares', { frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

This will create a 'red flare' emitter at 100 x 300.

Prior to 3.60 it would have looked like:

```js const manager = this.add.particles('flares');

const emitter = manager.createEmitter({ x: 100, y: 300, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 }); ```

The change is quite subtle but makes a big difference internally.

The biggest real change is with the particle x/y coordinates. It's important to understand that if you define x/y coordinates within the emitter configuration, they will be relative to those given in the add.particles call:

js const emitter = this.add.particles(100, 300, 'flares', { x: 100, y: 100, frame: 'red', angle: { min: -30, max: 30 }, speed: 150 });

In the above example the particles will emit from 200 x 400 in world space, because the emitter is at 100 x 300 and the particles emit from an offset of 100 x 100.

By making this change it now means you're able to do things like tween the x/y coordinates of the emitter (something you couldn't do before), or add a single emitter to a Container.

Other new features include:

Animated Particles

The Particle class now has an instance of the Animation State component within it. This allows a particle to play an animation when it is emitted, simply by defining it in the emitter config.

For example, this will make each particle play the 'Prism' animation on emission:

js const emitter = this.add.particles(400, 300, 'gems', { anim: 'prism' ... });

You can also allow it to select a random animation by providing an array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: [ 'prism', 'square', 'ruby', 'square' ] ... });

You've also the ability to cycle through the animations in order, so each new particle gets the next animation in the array:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'square', 'ruby', 'square' ], cycle: true } ... });

Or even set a quantity. For example, this will emit 10 'prism' particles, then 10 'ruby' particles and then repeat:

js const emitter = this.add.particles(400, 300, 'gems', { anim: { anims: [ 'prism', 'ruby' ], cycle: true, quantity: 10 } ... });

The Animations must have already been created in the Global Animation Manager and must use the same texture as the one bound to the Particle Emitter. Aside from this, you can still control them in the same way as any other particle - scaling, tinting, rotation, alpha, lifespan, etc.

Fast Forward Particle Time

  • You can now 'fast forward' a Particle Emitter. This can be done via either the emitter config, using the new advance property, or by calling the new ParticleEmitter.fastForward method. If, for example, you have an emitter that takes a few seconds to 'warm up' and get all the particles into position, this allows you to 'fast forward' the emitter to a given point in time. The value is given in ms. All standard emitter events and callbacks are still handled, but no rendering takes place during the fast-forward until it has completed.
  • The ParticleEmitter.start method has a new optional parameter advance that allows you to fast-forward the given amount of ms before the emitter starts flowing.

Particle Interpolation

  • It's now possible to create a new Interpolation EmitterOp. You do this by providing an array of values to interpolate between, along with the function name:

js const emitter = particles.createEmitter({ x: { values: [ 50, 500, 200, 800 ], interpolation: 'catmull' } ... });

This will interpolate the x property of each particle through the data set given, using a catmull rom interpolation function. You can also use linear or bezier functions. Interpolation can be combined with an ease type, which controls the progression through the time value. The related EmitterOpInterpolationConfig types have also been added.

Particle Emitter Duration

  • The Particle Emitter config has a new optional parameter duration:

js const emitter = particles.createEmitter({ speed: 24, lifespan: 1500, duration: 500 });

This parameter is used for 'flow' emitters only and controls how many milliseconds the emitter will run for before automatically turning itself off.

  • ParticleEmitter.duration is a new property that contains the duration that the Emitter will emit particles for in flow mode.
  • The ParticleEmitter.start method has a new optional parameter duration, which allows you to set the emitter duration when you call this method. If you do this, it will override any value set in the emitter configuration.
  • The ParticleEmitter.stop method has a new optional parameter kill. If set it will kill all alive particles immediately, rather than leaving them to die after their lifespan expires.

Stop After a set number of Particles

  • The Particle Emitter config has a new optional stopAfter property. This, combined with the frequency property allows you to control exactly how many particles are emitted before the emitter then stops:

js const emitter = particles.createEmitter({ x: { start: 400, end: 0 }, y: { start: 300, end: 0 }, lifespan: 3000, frequency: 250, stopAfter: 6, quantity: 1 });

In the above code the emitter will launch 1 particle (set by the quantity property) every 250 ms (set by the frequency property) and move it to xy 0x0. Once it has fired 6 particles (the stopAfter property) the emitter will stop and emit the COMPLETE event.

  • The stopAfter counter is reset each time you call the start or flow methods.

Particle Emitter Events

  • The Particle Emitter will now fire 5 new events. Listen for the events as follows:

```js const emitter = this.add.particles(0, 0, 'flares');

emitter.on('start', (emitter) => { // emission started });

emitter.on('explode', (emitter, particle) => { // emitter 'explode' called });

emitter.on('deathzone', (emitter, particle, deathzone) => { // emitter 'death zone' called });

emitter.on('stop', (emitter) => { // emission has stopped });

emitter.on('complete', (emitter) => { // all particles fully dead }); ```

  • The Particles.Events.START event is fired whenever the Emitter begins emission of particles in flow mode. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.EXPLODE event is fired whenever the Emitter explodes a bunch of particles via the explode method. A reference to the ParticleEmitter and a reference to the most recently fired Particle instance are the two parameters.
  • The Particles.Events.DEATH_ZONE event is fired whenever a Particle is killed by a Death Zone. A reference to the ParticleEmitter, the killed Particle and the DeathZone that caused it are the 3 parameters.
  • The Particles.Events.STOP event is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call the stop method, or when an Emitter hits its duration or stopAfter limit. A reference to the ParticleEmitter is included as the only parameter.
  • The Particles.Events.COMPLETE event is fired when the final alive particle expires.

Multiple Emit Zones

  • In v3.60 a Particle Emitter can now have multiple emission zones. Previously, an Emitter could have only a single emission zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addEmitZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addEmitZone({ type: 'edge', source: circle, quantity: 64 }); ```

  • When an Emitter has more than one emission zone, the Particles will cycle through the zones in sequence. For example, an Emitter with 3 zones would emit its first particle from zone 1, the second from zone 2, the third from zone 3, the fourth from zone 1, etc.
  • You can control how many particles are emitted from a single zone via the new total property. EdgeZone.total and RandomZone.total are new properties that control the total number of particles the zone will emit, before passing control over to the next zone in the list, if any. The default is -1.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeEmitZone is a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getEmitZone is a new method that Particles call when they are 'fired' in order to set their starting position, if any.
  • The property ParticleEmitter.emitZone has been removed. It has been replaced with the new ParticleEmitter.emitZones array-based property.

Multiple Death Zones

  • In v3.60 a Particle Emitter can now have multiple death zones. Previously, an Emitter could have only a single death zone. The zones can be created either via the Emitter Config by passing an array of zone objects, or via the new ParticleEmitter.addDeathZone method:

```js const circle = new Phaser.Geom.Circle(0, 0, 160);

const emitter = this.add.particles(400, 300, 'metal');

emitter.addDeathZone({ type: 'onEnter', source: circle }); ```

  • When an Emitter has more than one Death Zone, the Particles will check themselves against all of the Death Zones, to see if any of them kills them.
  • Because an Emitter now supports multiple Emit Zones, the method setEmitZone now performs a different task than before. It's now an alias for addEmitZone. This means if you call it multiple times, it will add multiple zones to the emitter, where-as before it would just replace the zone each time.
  • ParticleEmitter#removeDeathZone is a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.
  • ParticleEmitter.getDeathZone is a new method that Particles call when they are updated in order to check if they intersect with any of the Death Zones.
  • The property ParticleEmitter.deathZone has been removed. It has been replaced with the new ParticleEmitter.deathZones array-based property.

Particle Colors

  • You can now specify a new color property in the Emitter configuration. This takes the form of an array of hex color values that the particles will linearly interpolate between during theif lifetime. This allows you to now change the color of a particle from birth to death, which gives you far more control over your emitter visuals than ever before. You'd use it as follows:

js const flame = this.add.particles(150, 550, 'flares', { frame: 'white', color: [ 0xfacc22, 0xf89800, 0xf83600, 0x9f0404 ], colorEase: 'quad.out', lifespan: 2400, angle: { min: -100, max: -80 }, scale: { start: 0.70, end: 0, ease: 'sine.out' }, speed: 100, advance: 2000, blendMode: 'ADD' });

Here you can see the array of 4 colors it will interpolate through.

  • The new colorEase configuration property allows you to define the ease used to calculate the route through the interpolation. This can be set to any valid ease string, such as sine.out or quad.in, etc. If left undefined it will use linear as default.
  • EmitterColorOp is a brand new Emitter Op class that specifically controls the handling of color values, it extends EmitterOp and uses the same methods but configured for faster color interpolation.
  • If you define color in your config it will override any Emitter tint values you may have set. In short, use color if you wish to adjust the color of the particles during their lifespan and use tint if you wish to modify either the entire emitter at once, or the color of the particles on birth only.
  • ParticleEmitter.particleColor is a new property that allows you to get and set the particle color op value.
  • ParticleEmitter.colorEase is a new property that allows you to get and set the ease function used by the color op.

Particle Sort Order

  • You now have much more control over the sorting order of particles in an Emitter. You can set the new ParticleEmitter.sortProperty and sortOrderAsc properties to set how (and if) particles should be sorted prior to rendering. For example, setting sortProperty to y would mean that the particles will be sorted based on their y value prior to rendering. The sort order controls the order in which the particles are rendered. For example:

```js const emitter = this.add.particles(100, 300, 'blocks', { frame: 'redmonster', lifespan: 5000, angle: { min: -30, max: 30 }, speed: 150, frequency: 200 });

emitter.setSortProperty('y', true); ```

  • The new ParticleEmitter.setSortProperty method allows you to modify the sort property and order at run-time.
  • The new ParticleEmitter.setSortCallback method allows you to set a callback that will be invoked in order to sort the particles, rather than using the built-in one. This gives you complete freedom over the logic applied to particle render sorting.

Particle Bounds, Renderer Culling and Overlap

  • Particles now have the ability to calculate their bounding box, based on their position, scale, rotation, texture frame and the transform of their parent. You can call the new Particle.getBounds method to return the bounds, which also gets stored in the new Particle.bounds Rectangle property.
  • ParticleEmitter.getBounds is a new method that will return the bounds of the Emitter based on all currently active particles. Optional parameters allow you to pad out the bounds and/or advance time in the particle flow, to allow for a more accurate overall bounds generation.
  • ParticleEmitter.viewBounds is a new property that is a Geom Rectangle. Set this Rectangle to define the overall area the emitter will render to. If this area doesn't intersect with the Camera then the emitter will be culled from rendering. This allows you to populate large Scenes with active emitters that don't consume rendering resources even though they are offscreen. Use the new getBounds method to help define the viewBounds area.
  • ParticleEmitter.overlap is a new method that will run a rectangle intersection test against the given target and all alive particles, returning those that overlap in an array. The target can be a Rectangle Geometry object or an Arcade Physics Body.
  • Particle.kill is a new method that will set the life of the particle to zero, forcing it to be immediately killed on the next Particle Emitter update.
  • ParticleEmitter.getWorldTransformMatrix is a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.
  • ParticleEmitter.worldMatrix is a new property that holds a TransformMatrix used for bounds calculations.

Particle Processors

  • ParticleProcessor is a new base class that you can use to create your own Particle Processors, which are special processors capable of manipulating the path of Particles based on your own logic or math. It provides the structure required to handle the processing of particles and should be used as a base for your own classes.
  • GravityWell now extends the new ParticleProcessor class.
  • ParticleEmitter.addParticleProcessor is a new method that allows you to add a Particle Processor instance to the Emitter. The old createGravityWell method now uses this.
  • ParticleEmitter.removeParticleProcessor is a new method that will remove a Particle Processor from an Emitter.
  • ParticleEmitter.processors is a new List property that contains all of the Particle Processors belonging to the Emitter.
  • The ParticleEmitter.wells property has been removed. You should now use the new processors property instead, they are functionally identical.
  • ParticleProcessor.update is the method that handles all of the particle manipulation. It now has a new 4th parameter t that is the normalized lifespan of the Particle being processed.

Particle System EmitterOp Breaking Changes and Updates:

All of the following properties have been replaced on the ParticleEmitter class. Previously they were EmitterOp instances. They are now public getter / setters, so calling, for example, emitter.particleX will now return a numeric value - whereas before it would return the EmitterOp instance. This gives developers a lot more freedom when using Particle Emitters. Before v3.60 it was impossible to do this, for example:

js this.tweens.add({ targets: emitter, particleX: 400 });

I.e. you couldn't tween an emitters particle spawn position by directly accessing its x and y properties. However, now that all EmitterOps are getters, you're free to do this, allowing you to be much more creative and giving a nice quality-of-life improvement.

If, however, your code used to access EmitterOps, you'll need to change it as follows:

```js // Phaser 3.55 emitter.x.onChange(value) // Phaser 3.60 emitter.particleX = value

// Phaser 3.55 let x = emitter.x.propertyValue // Phaser 3.60 let x = emitter.particleX

// Phaser 3.55 emitter.x.onEmit() emitter.x.onUpdate() // Phaser 3.60 emitter.ops.x.onEmit() emitter.ops.x.onUpdate() ```

All of following EmitterOp functions can now be found in the new ParticleEmitter.ops property and have been replaced with getters:

  • accelerationX
  • accelerationY
  • alpha
  • angle
  • bounce
  • color
  • delay
  • lifespan
  • maxVelocityX
  • maxVelocityY
  • moveToX
  • moveToY
  • quantity
  • rotate
  • scaleX
  • scaleY
  • speedX
  • speedY
  • tint
  • x
  • y

Which means you can now directly access, modify and tween any of the above emitter properties at run-time while the emitter is active.

Another potentially breaking change is the removal of two internal private counters. These should never have been used directly anyway, but they are:

  • ParticleEmitter._counter - Now available via ParticleEmitter.flowCounter
  • ParticleEmitter._frameCounter - Now available via ParticleEmitter.frameCounter
  • EmitterOp._onEmit is a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyEmit method, to ensure that the Emitter current property remains current.
  • EmitterOp._onUpdate is a new private reference to the update callback function, if specified in the emitter configuration. It is called by the new EmitterOp.proxyUpdate method, to ensure that the Emitter current property remains current.
  • EmitterOp.destroy is a new method that nulls all references. This is called automatically when a ParticleEmitter is itself destroyed.

Further Particle System Updates and Fixes:

  • The Particle.resetPosition method has been renamed to setPosition and it now takes optional x/y parameters. If not given, it performs the same task as resetPosition did in earlier versions.
  • The ParticleEmitter class now has the AlphaSingle Component. This allows you to call setAlpha on the Emitter instance itself and have it impact all particles being rendered by it, allowing you to now 'fade in/out' a whole Emitter.
  • Setting frequency wasn't working correctly in earlier versions. It should allow you to specify a time, in ms, between which each 'quantity' of particles is emitted. However, the preUpdate loop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles.
  • Calling ParticleEmitter.start wouldn't reset the _frameCounter value internally, meaning the new emission didn't restart from the first texture frame again.
  • ParticleEmitter.counters is a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous _counter and _frameCounter properties have been merged into this array, along with new ones required for new features.
  • The WebGL Renderer will now use the new setQuad feature of the Transform Matrix. This vastly reduces the amount of math and function calls per particle, from 8 down to 1, increasing performance.
  • Particles with a scaleX or scaleY value of zero will no longer be rendered.
  • ParticleEmitter.preDestroy is a new method that will now clean-up all resources and internal arrays and destroy all Particles that the Emitter owns and clean-up all external references.
  • Particle.destroy is a new method that will clean up all external references and destroy the Animation State controller.
  • The ParticleEmitter._frameLength property is now specified on the class, rather than added dynamically at run-time, helping preserve class shape.
  • The ParticleEmitter.defaultFrame property has been removed as it's not required.
  • Calling ParticleEmitter.setFrame no longer resets the internal _frameCounter value to zero. Instead, the counter comparison has been hardened to >= instead of === to allow this value to change mid-emission and never reach the total.
  • The ParticleEmitter.configFastMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • The ParticleEmitter.configOpMap property has been moved to a local var within the ParticleEmitter JS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory.
  • Particle.scene is a new property that references the Scene the Particle Emitter belongs to.
  • Particle.anims is a new property that is an instance of the AnimationState component.
  • Particle.emit is a new proxy method that passes all Animation related events through to the Particle Emitter Manager to emit, as Particles cannot emit events directly.
  • Particle.isCropped is a new read-only property. Do not modify.
  • Particle.setSizeToFrame is a new internal NOOP method. Do not call.
  • ParticleEmitter.anims is a new property that contains the Animation keys that can be assigned to Particles.
  • ParticleEmitter.currentAnim is a new property that contains the index of the current animation, as tracked in cycle playback.
  • ParticleEmitter.randomAnim is a new boolean property that controls if the animations are selected randomly, or in a cycle.
  • ParticleEmitter.animQuantity is a new property that controls the number of consecutive particles that are emitted with the current animation.
  • ParticleEmitter.counters is a new internal Float32Array that holds all the counters the Emitter uses.
  • ParticleEmitter.getAnim is a new method, called by Particles when they are emitted, that will return the animation to use, if any.
  • ParticleEmitter.setAnim is a new method, called with the Emitter Manager, that sets the animation data into the Emitter.
  • The Particles.EmitterOp.toJSON method will now JSON stringify the property value before returning it.
  • Particles.EmitterOp.method is a new property that holds the current operation method being used. This is a read-only numeric value.
  • Particles.EmitterOp.active is a new boolean property that defines if the operator is alive, or not. This is now used by the Emitter instead of nulling Emitter properties, helping maintain class shape.
  • Particles.EmitterOp.getMethod is a new internal method that returns the operation function being used as a numeric value. This is then cached in the method property.
  • The Particles.EmitterOp.setMethods method has been updated so it now has a non-optional 'method' parameter. It has also been rewritten to be much more efficient, now being just a single simple select/case block.
  • The Particles.EmitterOp.onChange method will now use the cached 'method' property to avoid running through the setMethods function if not required, allowing each Particle EmitterOp to skip a huge chunk of code.
  • We've also greatly improved the documentation around the Particle classes.
  • ParticleEmitter.setConfig is a new method that allows you to set the configuration of the Emitter. Previously this was known as fromJSON.
  • The ParticleEmitter.setPosition method no longer changes the position of the particle emission point, but of the Emitter itself.
  • The ParticleEmitter.setBounds method has been renamed to setParticleBounds.
  • The ParticleEmitter.setSpeed method has been renamed to setParticleSpeed.
  • The ParticleEmitter.setScale method has been renamed to setParticleScale as setScale will now set the scale of the whole Emitter.
  • The ParticleEmitter.setScaleX and setScaleY methods have been removed. Please use setParticleScale.
  • The ParticleEmitter.setGravity method has been renamed to setParticleGravity.
  • The ParticleEmitter.setGravityX and setGravityY methods have been removed. Please use setParticleGravity.
  • The ParticleEmitter.setAlpha method has been renamed to setParticleAlpha as setAlpha will now set the alpha of the whole Emitter.
  • The ParticleEmitter.setTint method has been renamed to setParticleTint.
  • The ParticleEmitter.setLifespan method has been renamed to setParticleLifespan.
  • The ParticleEmitter.on property has been renamed to emitting to avoid conflicts with the Event Emitter.
  • The ParticleEmitter.x property has been renamed to particleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.y property has been renamed to particleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleX property has been renamed to particleScaleX and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.scaleY property has been renamed to particleScaleY and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.tint property has been renamed to particleTint and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.alpha property has been renamed to particleAlpha and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.angle property has been renamed to particleAngle and is a new EmitterOp capable of being tweened.
  • The ParticleEmitter.rotate property has been renamed to particleRotate and is a new EmitterOp capable of being tweened.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

TODO

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

  • The RenderTarget class will now create a Framebuffer that includes a Depth Stencil Buffer attachment by default. Previously, it didn't. By attaching a stencil buffer it allows things like Geometry Masks to work in combination with Post FX and other Pipelines. Fix #5802 (thanks @mijinc0)
  • When calling PipelineManager.clear and rebind it will now check if the vao extension is available, and if so, it'll bind a null vertex array. This helps clean-up from 3rd party libs that don't do this directly, such as ThreeJS.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • The batchLine method in the Multi Pipeline will now check to see if the dxdy len is zero, and if so, it will abort drawing the line. This fixes issues on older Android devices, such as the Samsung Galaxy S6 or Kindle 7, where it would draw erroneous lines leading up to the top-left of the canvas under WebGL when rendering a stroked rounded rectangle. Fix #5429 (thanks @fkoch-tgm @sreadixl)
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light fragment shader will now use the outTintEffect attribute meaning the Light Pipeline will now correctly light both tinted and fill-tinted Game Objects. Fix #5452 (thanks @kainage)
  • The Light Pipeline will now check to see if a Light2D enabled Game Object has a parent Container, or not, and factor the rotation and scale of this into the light calculation. Fix #6086 (thanks @irongaze)
  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been rewritten to help with performance, resolve some of its lingering issues and unifies the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • The Tween.seek method used to take a value between 0 and 1, based on how far through the Tween you wished to seek. However, it did not work with infinitely looping or repeating Tweens and would crash the browser tab. The new seek method takes a value in milliseconds instead and works perfectly on infinite Tweens.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as the source for a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • origin is now (0.5, 0.5) by default instead of (0, 0).

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Input System Updates

There are breaking changes from previous versions of Phaser.

  • The InteractiveObject.alwaysEnabled property has been removed. It is no longer checked within the InputPlugin and setting it will have no effect. This property has not worked correctly since version 3.52 when the new render list was implemented. Upon further investigation we decided to remove the property entirely, rather than shoe-horn it into the render list. If you need to create a non-rendering Interactive area, use the Zone Game Object instead.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.
  • The GameObjects.Components.Mask.createBitmapMask method can now accept the x, y, texture and frame parameters new to the BitmapMask constructor.
  • Previously, calling createBitmapMask on a Shape Game Object would fail unless you passed the shape to the method. Now, it will correctly create a mask from the Shape without needing to pass it. Fix #5976 (thanks @samme)

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • The Graphics.strokeRoundedRect and fillRoundedRect methods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow)
  • AnimationManager.getAnimsFromTexture is a new method that will return all global Animations, as stored in the Animation Manager, that have at least one frame using the given Texture. This will not include animations created directly on local Sprites.
  • BitmapText.setLineSpacing is a new method that allows you to set the vertical spacing between lines in multi-line BitmapText Game Objects. It works in the same was as spacing for Text objects and the spacing value can be positive or negative. See also BitmapText.lineSpacing for the property rather than the method.
  • WebGLPipeline.vertexAvailable is a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.
  • The Tilemap and TilemapLayer classes have a new method getTileCorners. This method will return an array of Vector2s with each entry corresponding to the corners of the requested tile, in world space. This currently works for Orthographic and Hexagonal tilemaps.
  • BaseSoundManager.getAllPlaying is a new method that will return all currently playing sounds in the Sound Manager.
  • Animation.showBeforeDelay is a new optional boolean property you can set when creating, or playing an animation. If the animation has a delay before playback starts this controls if it should still set the first frame immediately, or after the delay has expired (the default).
  • InputPlugin.resetPointers is a new method that will loop through all of the Input Manager Pointer instances and reset them all. This is useful if a 3rd party component, such as Vue, has stolen input from Phaser and you need to reset its input state again.
  • Pointer.reset is a new method that will reset a Pointer instance back to its 'factory' settings.
  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • The Game.registry, which is a DataManager instance that can be used as a global store of game wide data will now use its own Event Emitter, instead of the Game's Event Emitter. This means it's perfectly safe for you to now use the Registry to emit and listen for your own custom events without conflicting with events the Phaser Game instance emits.
  • The GenerateVerts function has a new optional parameter flipUV which, if set, will flip the UV texture coordinates (thanks cedarcantab)
  • The GenerateVerts function no longer errors if the verts and uvs arrays are not the same size and containsZ is true (thanks cedarcantab)
  • The Device.Browser checks for Opera and Edge have been updated to use the more modern user agent strings those browsers now use. This breaks compatibility with really old versions of those browsers but fixes it for modern ones (which is more important) (thanks @ ArtemSiz)
  • The SceneManager.processQueue method will no longer return if a new Scene was added, after starting it. This allows any other queued operations to still be run in the same frame, rather than being delayed until the next game frame. Fix #5359 (thanks @telinc1)
  • Camera.scrollX and scrollY will now only set the Camera.dirty flag to true if the new value given to them is different from their current value. This allows you to use this property in your own culling functions. Fix #6088 (thanks @Waclaw-I)
  • Face.update is a new method that updates each of the Face vertices. This is now called internally by Face.isInView.
  • Vertex.resize is a new method that will set the position and then translate the Vertex based on an identity matrix.
  • The Vertex.update method now returns this to allow it to be chained.
  • You can now optionally specify the maxSpeed value in the Arcade Physics Group config (thanks @samme)
  • You can now optionally specify the useDamping boolean in the Arcade Physics Group config (thanks @samme)
  • Removed the HexagonalTileToWorldY function as it cannot work without an X coordinate. Use HexagonalTileToWorldXY instead.
  • Removed the HexagonalWorldToTileY function as it cannot work without an X coordinate. Use HexagonalWorldToTileXY instead.
  • Earcut has been updated to version 2.2.4. This release improves performance by 10-15% and fixes 2 rare race conditions that could leave to infinite loops. Earcut is used internally by Graphics and Shape game objects when triangulating polygons for complex shapes.
  • The BaseSoundManager.getAll method used to require a key parameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned.
  • The WebAudioSoundManager will now detect if the Audio Context enters a 'suspended' or 'interrupted' state as part of its update loop and if so it'll try to resume the context. This can happen if you change or disable the audio device, such as plugging in headphones with built-in audio drivers then disconnecting them, or swapping tabs on iOS. Fix #5353 (thanks @helloyoucan)
  • The CONTEXT_RESTORED Game Event has been removed and the WebGL Renderer no longer listens for the contextrestored DOM event, or has a contextRestoredHandler method. This never actually worked properly, in any version of Phaser 3 - although the WebGLRenderer would be restored, none of the shaders, pipelines or textures were correctly re-created. If a context is now lost, Phaser will display an error in the console and all rendering will halt. It will no longer try to re-create the context, leading to masses of WebGL errors in the console. Instead, it will die gracefully and require a page reload.
  • The Text and TileSprite Game Objects no longer listen for the CONTEXT_RESTORED event and have had their onContextRestored methods removed.
  • Scenes.Systems.canInput is a new internal method that determines if a Scene can receive Input events, or not. This is now used by the InputPlugin instead of the previous isActive test. This allows a Scene to emit and handle input events even when it is running init or preload. Previously, it could only do this after create had finished running. Fix #6123 (thanks @yaasinhamidi)
  • The BitmapText Game Object has two new read-only properties displayWidth and displayHeight. This allows the BitmapText to correctly use the GetBounds component.
  • The BitmapText Game Object now has the GetBounds component added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames)
  • WebGLSnapshot will now flip the pixels in the created Image element if the source was a framebuffer. This means grabbing a snapshot from a Dynamic or Render Texture will now correctly invert the pixels on the y axis for an Image. Grabbing from the game renderer will skip this.
  • WebGLRenderer.snapshotFramebuffer and by extension, the snapshot methods in Dynamic Textures and Render Textures, has been updated to ensure that the width and height never exceed the framebuffer dimensions, or it'll cause a runtime error. The method snapshotArea has had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)
  • Animation.stop is always called when a new animation is loaded, regardless if the animation was playing or not and the delayCounter is reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)
  • ScaleManager.listeners has been renamed to domlisteners to avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)
  • Geom.Intersects.LineToLine will no longer create an internal Point object, as it's not required internally (thanks @Trissolo)
  • The tempZone used by GridAlign has now had setOrigin(0, 0) applied to it. This leads to more accurate / expected zone placement when aligning grid items.
  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • The maxSpeed setting in Arcade Physics wasn't recalculated during the Body update, prior to being compared, leading to inconsistent results. Fix #6329 (thanks @Bambosh)
  • Several paths have been fixed in the phaser-core.js entry point (thanks @pavle-goloskokovic)
  • When a Game Object had Input Debug Enabled the debug image would be incorrectly offset if the Game Object was attached to was scaled and the hit area shape was smaller, or offset, from the Game Object. Fix #4905 #6317 (thanks @PavelMishin @justinlueders)
  • An inactive Scene is no longer updated after a Scene transition completes. Previously, it will still update the Scene one final time. This fix also prevents the POST_UPDATE event from firing after the transition is over. Fix #5550 (thanks @mijinc0 @samme)
  • Although not recommended, when adding a Layer Game Object to another Layer Game Object, it will no longer error because it cannot find the removeFromDisplayList function. Fix #5595 (thanks @tringcooler)
  • The Actions.Spread method will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV)
  • Calling setDisplayOrigin on a Video Game Object would cause the origins to be set to NaN if the Video was created without an asset key. It will now give Videos a default size, preventing this error, which is reset once a video is loaded. Fix #5560 (thanks @mattjennings)
  • When ImageFile loads with a linked Normal Map and the map completes first, but the Image is still in a pending state, it would incorrectly add itself to the cache instead of waiting. It now checks this process more carefully. Fix #5886 (thanks @inmylo)
  • Using a dataKey to specify a part of a JSON file when using load.pack would fail as it wouldn't correctly assign the right part of the pack file to the Loader. You can now use this parameter properly. Fix #6001 (thanks @rexrainbow)
  • The Text.advancedWordWrap function would incorrectly merge the current and next lines when wrapping words with carriage-returns in. Fix #6187 (thanks @Ariorh1337 @robinheidrich)
  • Recoded the point conversion math in the HexagonalTileToWorldXY function as it was incorrect. Now returns world coordinates correctly.
  • Tilemap.copy would error if you copied a block of tiles over itself, even partially, as it tried to copy already replaced tiles as part of the function. It will now copy correctly, regardless of source or destination areas. Fix #6188 (thanks @Arkyris)
  • Tile.copy will now use the DeepCopy function to copy the Tile.properties object, as otherwise it just gets copied by reference.
  • Recoded the point conversion math in the HexagonalWorldToTileXY function as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich)
  • Fixed the point conversion math in the IsometricWorldToTileXY function and added optional boolean property that allows the setting of the tile origin to the top or base. Fix #5781 (thanks @benjamin-wilson)
  • Calling Tilemap.worldToTileX or worldToTileY on a Isometric or Hexagonal Tilemap will now always return null instead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should use worldToTileXY instead.
  • The Game.headlessStep method will now reset SceneManager.isProcessing before PRE_RENDER. This fixes issues in HEADLESS mode where the Scene Manager wouldn't process additionally added Scenes created after the Game had started. Fix #5872 #5974 (thanks @micsun-al @samme)
  • If Rope.setPoints was called with the exact same number of points as before, it wouldn't set the dirty flag, meaning the vertices were not updated on the next render (thanks @stupot)
  • Particle.fire will now check to see if the parent Emitter is set to follow a Game Object and if so, and if the x/y EmitterOps are spread ops, then it'll space the particles out based on the follower coordinates, instead of clumping them all together. Fix #5847 (thanks @sreadixl)
  • When using RTL (right-to-left) Text Game Objects, the Text would vanish on iOS15+ if you changed the text or font style. The context RTL properties are now restored when the text is updated, fixing this issue. Fix #6121 (thanks @liorGameDev)
  • The Tilemap.destroyLayer method would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme)
  • MapData and ObjectLayer will now enforce that the Tilemap.objects property is always an array. Sometimes Tiled willl set it to be a blank object in the JSON data. This fix makes sure it is always an array. Fix #6139 (thanks @robbeman)
  • The ParseJSONTiled function will now run a DeepCopy on the source Tiled JSON, which prevents object mutation, fixing an issue where Tiled Object Layer names would be duplicated if used across multiple Tilemap instances. Fix #6212 (thanks @temajm @wahur666)
  • The method Color.setFromHSV would not change the members h, s and v, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow)
  • When calling GameObject.getPostPipeline and passing in a string for the pipeline name it would error with 'Uncaught TypeError: Right-hand side of 'instanceof' is not an object'. This is now handled correctly internally (thanks @neki-dev)
  • When playing a chained animation, the nextAnim property could get set to undefined which would stop the next animation in the queue from being set. The check now handles all falsey cases. Fix #5852 (thanks @Pythux)
  • When calling InputPlugin.clear it will now call removeDebug on the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton)
  • The Video.loadURL method wouldn't load the video or emit the VIDEO_CREATED event unless noAudio was specified. A load event handler has been added to resolve this (thanks @samme)
  • If you create a repeating or looping TimerEvent with a delay of zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan)
  • The endFrame and startFrame properties of the SpriteSheet parser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the given startFrame so that is frame zero and end at endFrame, regardless how many other frames are in the sheet.
  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)
  • Sprites created directly (not via the Game Object Factory) which are then added to a Container would fail to play their animations, because they were not added to the Scene Update List. Fix #5817 #5818 #6052 (thanks @prakol16 @adomas-sk)
  • Game Objects that were created and destroyed (or moved to Containers) in the same frame were not correctly removed from the UpdateList. Fix #5803 (thanks @samme)
  • Container.removeHandler now specifies the context for Events.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would cause sys reference errors. Fix 5846 (thanks @sreadixl)
  • Container.removeAll (which is also called when a Container is destroyed) will now directly destroy the children, if the given parameter is set, rather than doing it after removing them via the event handler. This fixes an issue where nested Containers would add destroyed children back to the Scene as part of their shutdown process. Fix #6078 (thanks @BenoitFreslon)
  • The DisplayList.addChildCallback method will now check to see if the child has a parent container, and if it does, remove it from there before adding it to the Scene Display List. Fix #6091 (thanks @michalfialadev)
  • Display.RGB.equals will now return the correct result. Previously, it would always return false (thanks @samme)
  • When destroying the Arcade Physics World it will now destroy the debug Graphics object, had one been created. Previously, these would continue to stack-up should you restart the physics world (thanks @samme)
  • Graphics.strokeRoundedRect would incorrectly draw the rectangle if you passed in a radius greater than half of the smaller side. This is now clamped internally (thanks @temajm)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@0day-oni @201flaviosilva @AlbertMontagutCasero @Arcanorum @arosemena @austinlyon @chrisl8 @christian-post @danfoster @darrylpizarro @DeweyHur @ef4 @eltociear @EsteFilipe @etherealmachine @Fake @florestankorp @hacheraw @hanzooo @jerricko @joegaffey @jonasrundberg @kootoopas @lolimay @MaffDev @michalfialadev @monteiz @necrokot @Nero0 @orjandh @PhaserEditor2D @Pythux @quocsinh @rgk @rollinsafary-inomma @rstanuwijaya @samme @Smirnov48 @steveja42 @sylvainpolletvillard @twoco @ubershmekel @VanaMartin @vforsh @Vidminas @x-wk @xmahle @xuxucode @YeloPartyHat FromChris Golen OmniOwl

- JavaScript
Published by photonstorm over 3 years ago

phaser - Phaser 3.60 Beta 17

Version 3.60.0 - Miku - in development

New Features - Nine Slice Game Object

Phaser 3.60 contains a new native Nine Slice Game Object. A Nine Slice Game Object allows you to display a texture-based object that can be stretched both horizontally and vertically, but that retains fixed-sized corners. The dimensions of the corners are set via the parameters to the class. When you resize a Nine Slice Game Object only the middle sections of the texture stretch. This is extremely useful for UI and button-like elements, where you need them to expand to accomodate the content without distorting the texture.

The texture you provide for this Game Object should be based on the following layout structure:

A B +---+----------------------+---+ C | 1 | 2 | 3 | +---+----------------------+---+ | | | | | 4 | 5 | 6 | | | | | +---+----------------------+---+ D | 7 | 8 | 9 | +---+----------------------+---+

When changing this objects width and / or height:

areas 1, 3, 7 and 9 (the corners) will remain unscaled
areas 2 and 8 will be stretched horizontally only
areas 4 and 6 will be stretched vertically only
area 5 will be stretched both horizontally and vertically

You can also create a 3 slice Game Object:

This works in a similar way, except you can only stretch it horizontally. Therefore, it requires less configuration:

A B +---+----------------------+---+ | | | | C | 1 | 2 | 3 | | | | | +---+----------------------+---+

When changing this objects width (you cannot change its height)

areas 1 and 3 will remain unscaled
area 2 will be stretched horizontally

The above configuration concept is adapted from the Pixi NineSlicePlane.

To specify a 3 slice object instead of a 9 slice you should only provide the leftWidth and rightWidth parameters. To create a 9 slice you must supply all parameters.

The minimum width this Game Object can be is the total of leftWidth + rightWidth. 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 scale it.

In terms of performance, using a 3 slice Game Object is the equivalent of having 3 Sprites in a row. Using a 9 slice Game Object is the equivalent of having 9 Sprites in a row. The vertices of this object are all batched together and can co-exist with other Sprites and graphics on the display list, without incurring any additional overhead.

As of Phaser 3.60 this Game Object is WebGL only. Please see the new examples and documentation for how to use it.

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

  • The RenderTarget class will now create a Framebuffer that includes a Depth Stencil Buffer attachment by default. Previously, it didn't. By attaching a stencil buffer it allows things like Geometry Masks to work in combination with Post FX and other Pipelines. Fix #5802 (thanks @mijinc0)
  • When calling PipelineManager.clear and rebind it will now check if the vao extension is available, and if so, it'll bind a null vertex array. This helps clean-up from 3rd party libs that don't do this directly, such as ThreeJS.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • The batchLine method in the Multi Pipeline will now check to see if the dxdy len is zero, and if so, it will abort drawing the line. This fixes issues on older Android devices, such as the Samsung Galaxy S6 or Kindle 7, where it would draw erroneous lines leading up to the top-left of the canvas under WebGL when rendering a stroked rounded rectangle. Fix #5429 (thanks @fkoch-tgm @sreadixl)
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light fragment shader will now use the outTintEffect attribute meaning the Light Pipeline will now correctly light both tinted and fill-tinted Game Objects. Fix #5452 (thanks @kainage)
  • The Light Pipeline will now check to see if a Light2D enabled Game Object has a parent Container, or not, and factor the rotation and scale of this into the light calculation. Fix #6086 (thanks @irongaze)
  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been rewritten to help with performance, resolve some of its lingering issues and unifies the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • The Tween.seek method used to take a value between 0 and 1, based on how far through the Tween you wished to seek. However, it did not work with infinitely looping or repeating Tweens and would crash the browser tab. The new seek method takes a value in milliseconds instead and works perfectly on infinite Tweens.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as the source for a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • origin is now (0.5, 0.5) by default instead of (0, 0).

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Input System Updates

There are breaking changes from previous versions of Phaser.

  • The InteractiveObject.alwaysEnabled property has been removed. It is no longer checked within the InputPlugin and setting it will have no effect. This property has not worked correctly since version 3.52 when the new render list was implemented. Upon further investigation we decided to remove the property entirely, rather than shoe-horn it into the render list. If you need to create a non-rendering Interactive area, use the Zone Game Object instead.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.
  • The GameObjects.Components.Mask.createBitmapMask method can now accept the x, y, texture and frame parameters new to the BitmapMask constructor.
  • Previously, calling createBitmapMask on a Shape Game Object would fail unless you passed the shape to the method. Now, it will correctly create a mask from the Shape without needing to pass it. Fix #5976 (thanks @samme)

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • BitmapText.setLineSpacing is a new method that allows you to set the vertical spacing between lines in multi-line BitmapText Game Objects. It works in the same was as spacing for Text objects and the spacing value can be positive or negative. See also BitmapText.lineSpacing for the property rather than the method.
  • WebGLPipeline.vertexAvailable is a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.
  • The Tilemap and TilemapLayer classes have a new method getTileCorners. This method will return an array of Vector2s with each entry corresponding to the corners of the requested tile, in world space. This currently works for Orthographic and Hexagonal tilemaps.
  • BaseSoundManager.getAllPlaying is a new method that will return all currently playing sounds in the Sound Manager.
  • Animation.showBeforeDelay is a new optional boolean property you can set when creating, or playing an animation. If the animation has a delay before playback starts this controls if it should still set the first frame immediately, or after the delay has expired (the default).
  • InputPlugin.resetPointers is a new method that will loop through all of the Input Manager Pointer instances and reset them all. This is useful if a 3rd party component, such as Vue, has stolen input from Phaser and you need to reset its input state again.
  • Pointer.reset is a new method that will reset a Pointer instance back to its 'factory' settings.
  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • Camera.scrollX and scrollY will now only set the Camera.dirty flag to true if the new value given to them is different from their current value. This allows you to use this property in your own culling functions. Fix #6088 (thanks @Waclaw-I)
  • Face.update is a new method that updates each of the Face vertices. This is now called internally by Face.isInView.
  • Vertex.resize is a new method that will set the position and then translate the Vertex based on an identity matrix.
  • The Vertex.update method now returns this to allow it to be chained.
  • You can now optionally specify the maxSpeed value in the Arcade Physics Group config (thanks @samme)
  • You can now optionally specify the useDamping boolean in the Arcade Physics Group config (thanks @samme)
  • Removed the HexagonalTileToWorldY function as it cannot work without an X coordinate. Use HexagonalTileToWorldXY instead.
  • Removed the HexagonalWorldToTileY function as it cannot work without an X coordinate. Use HexagonalWorldToTileXY instead.
  • Earcut has been updated to version 2.2.4. This release improves performance by 10-15% and fixes 2 rare race conditions that could leave to infinite loops. Earcut is used internally by Graphics and Shape game objects when triangulating polygons for complex shapes.
  • The BaseSoundManager.getAll method used to require a key parameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned.
  • The WebAudioSoundManager will now detect if the Audio Context enters a 'suspended' or 'interrupted' state as part of its update loop and if so it'll try to resume the context. This can happen if you change or disable the audio device, such as plugging in headphones with built-in audio drivers then disconnecting them, or swapping tabs on iOS. Fix #5353 (thanks @helloyoucan)
  • The CONTEXT_RESTORED Game Event has been removed and the WebGL Renderer no longer listens for the contextrestored DOM event, or has a contextRestoredHandler method. This never actually worked properly, in any version of Phaser 3 - although the WebGLRenderer would be restored, none of the shaders, pipelines or textures were correctly re-created. If a context is now lost, Phaser will display an error in the console and all rendering will halt. It will no longer try to re-create the context, leading to masses of WebGL errors in the console. Instead, it will die gracefully and require a page reload.
  • The Text and TileSprite Game Objects no longer listen for the CONTEXT_RESTORED event and have had their onContextRestored methods removed.
  • Scenes.Systems.canInput is a new internal method that determines if a Scene can receive Input events, or not. This is now used by the InputPlugin instead of the previous isActive test. This allows a Scene to emit and handle input events even when it is running init or preload. Previously, it could only do this after create had finished running. Fix #6123 (thanks @yaasinhamidi)
  • The BitmapText Game Object has two new read-only properties displayWidth and displayHeight. This allows the BitmapText to correctly use the GetBounds component.
  • The BitmapText Game Object now has the GetBounds component added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames)
  • WebGLSnapshot will now flip the pixels in the created Image element if the source was a framebuffer. This means grabbing a snapshot from a Dynamic or Render Texture will now correctly invert the pixels on the y axis for an Image. Grabbing from the game renderer will skip this.
  • WebGLRenderer.snapshotFramebuffer and by extension, the snapshot methods in Dynamic Textures and Render Textures, has been updated to ensure that the width and height never exceed the framebuffer dimensions, or it'll cause a runtime error. The method snapshotArea has had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)
  • Animation.stop is always called when a new animation is loaded, regardless if the animation was playing or not and the delayCounter is reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)
  • ScaleManager.listeners has been renamed to domlisteners to avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)
  • Geom.Intersects.LineToLine will no longer create an internal Point object, as it's not required internally (thanks @Trissolo)
  • The tempZone used by GridAlign has now had setOrigin(0, 0) applied to it. This leads to more accurate / expected zone placement when aligning grid items.
  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • The Actions.Spread method will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV)
  • Calling setDisplayOrigin on a Video Game Object would cause the origins to be set to NaN if the Video was created without an asset key. It will now give Videos a default size, preventing this error, which is reset once a video is loaded. Fix #5560 (thanks @mattjennings)
  • When ImageFile loads with a linked Normal Map and the map completes first, but the Image is still in a pending state, it would incorrectly add itself to the cache instead of waiting. It now checks this process more carefully. Fix #5886 (thanks @inmylo)
  • Using a dataKey to specify a part of a JSON file when using load.pack would fail as it wouldn't correctly assign the right part of the pack file to the Loader. You can now use this parameter properly. Fix #6001 (thanks @rexrainbow)
  • The Text.advancedWordWrap function would incorrectly merge the current and next lines when wrapping words with carriage-returns in. Fix #6187 (thanks @Ariorh1337 @robinheidrich)
  • Recoded the point conversion math in the HexagonalTileToWorldXY function as it was incorrect. Now returns world coordinates correctly.
  • Tilemap.copy would error if you copied a block of tiles over itself, even partially, as it tried to copy already replaced tiles as part of the function. It will now copy correctly, regardless of source or destination areas. Fix #6188 (thanks @Arkyris)
  • Tile.copy will now use the DeepCopy function to copy the Tile.properties object, as otherwise it just gets copied by reference.
  • Recoded the point conversion math in the HexagonalWorldToTileXY function as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich)
  • Fixed the point conversion math in the IsometricWorldToTileXY function and added optional boolean property that allows the setting of the tile origin to the top or base. Fix #5781 (thanks @benjamin-wilson)
  • Calling Tilemap.worldToTileX or worldToTileY on a Isometric or Hexagonal Tilemap will now always return null instead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should use worldToTileXY instead.
  • The Game.headlessStep method will now reset SceneManager.isProcessing before PRE_RENDER. This fixes issues in HEADLESS mode where the Scene Manager wouldn't process additionally added Scenes created after the Game had started. Fix #5872 #5974 (thanks @micsun-al @samme)
  • If Rope.setPoints was called with the exact same number of points as before, it wouldn't set the dirty flag, meaning the vertices were not updated on the next render (thanks @stupot)
  • Particle.fire will now check to see if the parent Emitter is set to follow a Game Object and if so, and if the x/y EmitterOps are spread ops, then it'll space the particles out based on the follower coordinates, instead of clumping them all together. Fix #5847 (thanks @sreadixl)
  • When using RTL (right-to-left) Text Game Objects, the Text would vanish on iOS15+ if you changed the text or font style. The context RTL properties are now restored when the text is updated, fixing this issue. Fix #6121 (thanks @liorGameDev)
  • The Tilemap.destroyLayer method would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme)
  • MapData and ObjectLayer will now enforce that the Tilemap.objects property is always an array. Sometimes Tiled willl set it to be a blank object in the JSON data. This fix makes sure it is always an array. Fix #6139 (thanks @robbeman)
  • The ParseJSONTiled function will now run a DeepCopy on the source Tiled JSON, which prevents object mutation, fixing an issue where Tiled Object Layer names would be duplicated if used across multiple Tilemap instances. Fix #6212 (thanks @temajm @wahur666)
  • The method Color.setFromHSV would not change the members h, s and v, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow)
  • When calling GameObject.getPostPipeline and passing in a string for the pipeline name it would error with 'Uncaught TypeError: Right-hand side of 'instanceof' is not an object'. This is now handled correctly internally (thanks @neki-dev)
  • When playing a chained animation, the nextAnim property could get set to undefined which would stop the next animation in the queue from being set. The check now handles all falsey cases. Fix #5852 (thanks @Pythux)
  • When calling InputPlugin.clear it will now call removeDebug on the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton)
  • The Video.loadURL method wouldn't load the video or emit the VIDEO_CREATED event unless noAudio was specified. A load event handler has been added to resolve this (thanks @samme)
  • If you create a repeating or looping TimerEvent with a delay of zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan)
  • The endFrame and startFrame properties of the SpriteSheet parser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the given startFrame so that is frame zero and end at endFrame, regardless how many other frames are in the sheet.
  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)
  • Sprites created directly (not via the Game Object Factory) which are then added to a Container would fail to play their animations, because they were not added to the Scene Update List. Fix #5817 #5818 #6052 (thanks @prakol16 @adomas-sk)
  • Game Objects that were created and destroyed (or moved to Containers) in the same frame were not correctly removed from the UpdateList. Fix #5803 (thanks @samme)
  • Container.removeHandler now specifies the context for Events.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would cause sys reference errors. Fix 5846 (thanks @sreadixl)
  • Container.removeAll (which is also called when a Container is destroyed) will now directly destroy the children, if the given parameter is set, rather than doing it after removing them via the event handler. This fixes an issue where nested Containers would add destroyed children back to the Scene as part of their shutdown process. Fix #6078 (thanks @BenoitFreslon)
  • The DisplayList.addChildCallback method will now check to see if the child has a parent container, and if it does, remove it from there before adding it to the Scene Display List. Fix #6091 (thanks @michalfialadev)
  • Display.RGB.equals will now return the correct result. Previously, it would always return false (thanks @samme)
  • When destroying the Arcade Physics World it will now destroy the debug Graphics object, had one been created. Previously, these would continue to stack-up should you restart the physics world (thanks @samme)
  • Graphics.strokeRoundedRect would incorrectly draw the rectangle if you passed in a radius greater than half of the smaller side. This is now clamped internally (thanks @temajm)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@201flaviosilva @AlbertMontagutCasero @Arcanorum @arosemena @austinlyon @chrisl8 @christian-post @danfoster @darrylpizarro @DeweyHur @ef4 @eltociear @EsteFilipe @etherealmachine @Fake @florestankorp @hacheraw @hanzooo @jerricko @joegaffey @jonasrundberg @kootoopas @lolimay @michalfialadev @monteiz @necrokot @Nero0 @orjandh @PhaserEditor2D @Pythux @quocsinh @rgk @rollinsafary-inomma @rstanuwijaya @samme @Smirnov48 @steveja42 @sylvainpolletvillard @twoco @ubershmekel @VanaMartin @vforsh @Vidminas @x-wk @xmahle @xuxucode @YeloPartyHat FromChris Golen OmniOwl

- JavaScript
Published by photonstorm over 3 years ago

phaser - Phaser 3.60 Beta 16

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

  • The RenderTarget class will now create a Framebuffer that includes a Depth Stencil Buffer attachment by default. Previously, it didn't. By attaching a stencil buffer it allows things like Geometry Masks to work in combination with Post FX and other Pipelines. Fix #5802 (thanks @mijinc0)
  • When calling PipelineManager.clear and rebind it will now check if the vao extension is available, and if so, it'll bind a null vertex array. This helps clean-up from 3rd party libs that don't do this directly, such as ThreeJS.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • The batchLine method in the Multi Pipeline will now check to see if the dxdy len is zero, and if so, it will abort drawing the line. This fixes issues on older Android devices, such as the Samsung Galaxy S6 or Kindle 7, where it would draw erroneous lines leading up to the top-left of the canvas under WebGL when rendering a stroked rounded rectangle. Fix #5429 (thanks @fkoch-tgm @sreadixl)
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light fragment shader will now use the outTintEffect attribute meaning the Light Pipeline will now correctly light both tinted and fill-tinted Game Objects. Fix #5452 (thanks @kainage)
  • The Light Pipeline will now check to see if a Light2D enabled Game Object has a parent Container, or not, and factor the rotation and scale of this into the light calculation. Fix #6086 (thanks @irongaze)
  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been rewritten to help with performance, resolve some of its lingering issues and unifies the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • The Tween.seek method used to take a value between 0 and 1, based on how far through the Tween you wished to seek. However, it did not work with infinitely looping or repeating Tweens and would crash the browser tab. The new seek method takes a value in milliseconds instead and works perfectly on infinite Tweens.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as the source for a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • origin is now (0.5, 0.5) by default instead of (0, 0).

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.
  • The GameObjects.Components.Mask.createBitmapMask method can now accept the x, y, texture and frame parameters new to the BitmapMask constructor.
  • Previously, calling createBitmapMask on a Shape Game Object would fail unless you passed the shape to the method. Now, it will correctly create a mask from the Shape without needing to pass it. Fix #5976 (thanks @samme)

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • The Tilemap and TilemapLayer classes have a new method getTileCorners. This method will return an array of Vector2s with each entry corresponding to the corners of the requested tile, in world space. This currently works for Orthographic and Hexagonal tilemaps.
  • BaseSoundManager.getAllPlaying is a new method that will return all currently playing sounds in the Sound Manager.
  • Animation.showBeforeDelay is a new optional boolean property you can set when creating, or playing an animation. If the animation has a delay before playback starts this controls if it should still set the first frame immediately, or after the delay has expired (the default).
  • InputPlugin.resetPointers is a new method that will loop through all of the Input Manager Pointer instances and reset them all. This is useful if a 3rd party component, such as Vue, has stolen input from Phaser and you need to reset its input state again.
  • Pointer.reset is a new method that will reset a Pointer instance back to its 'factory' settings.
  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • You can now optionally specify the maxSpeed value in the Arcade Physics Group config (thanks @samme)
  • You can now optionally specify the useDamping boolean in the Arcade Physics Group config (thanks @samme)
  • Removed the HexagonalTileToWorldY function as it cannot work without an X coordinate. Use HexagonalTileToWorldXY instead.
  • Removed the HexagonalWorldToTileY function as it cannot work without an X coordinate. Use HexagonalWorldToTileXY instead.
  • Earcut has been updated to version 2.2.4. This release improves performance by 10-15% and fixes 2 rare race conditions that could leave to infinite loops. Earcut is used internally by Graphics and Shape game objects when triangulating polygons for complex shapes.
  • The BaseSoundManager.getAll method used to require a key parameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned.
  • The WebAudioSoundManager will now detect if the Audio Context enters a 'suspended' or 'interrupted' state as part of its update loop and if so it'll try to resume the context. This can happen if you change or disable the audio device, such as plugging in headphones with built-in audio drivers then disconnecting them, or swapping tabs on iOS. Fix #5353 (thanks @helloyoucan)
  • The CONTEXT_RESTORED Game Event has been removed and the WebGL Renderer no longer listens for the contextrestored DOM event, or has a contextRestoredHandler method. This never actually worked properly, in any version of Phaser 3 - although the WebGLRenderer would be restored, none of the shaders, pipelines or textures were correctly re-created. If a context is now lost, Phaser will display an error in the console and all rendering will halt. It will no longer try to re-create the context, leading to masses of WebGL errors in the console. Instead, it will die gracefully and require a page reload.
  • The Text and TileSprite Game Objects no longer listen for the CONTEXT_RESTORED event and have had their onContextRestored methods removed.
  • Scenes.Systems.canInput is a new internal method that determines if a Scene can receive Input events, or not. This is now used by the InputPlugin instead of the previous isActive test. This allows a Scene to emit and handle input events even when it is running init or preload. Previously, it could only do this after create had finished running. Fix #6123 (thanks @yaasinhamidi)
  • The BitmapText Game Object has two new read-only properties displayWidth and displayHeight. This allows the BitmapText to correctly use the GetBounds component.
  • The BitmapText Game Object now has the GetBounds component added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames)
  • WebGLSnapshot will now flip the pixels in the created Image element if the source was a framebuffer. This means grabbing a snapshot from a Dynamic or Render Texture will now correctly invert the pixels on the y axis for an Image. Grabbing from the game renderer will skip this.
  • WebGLRenderer.snapshotFramebuffer and by extension, the snapshot methods in Dynamic Textures and Render Textures, has been updated to ensure that the width and height never exceed the framebuffer dimensions, or it'll cause a runtime error. The method snapshotArea has had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)
  • Animation.stop is always called when a new animation is loaded, regardless if the animation was playing or not and the delayCounter is reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)
  • ScaleManager.listeners has been renamed to domlisteners to avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)
  • Geom.Intersects.LineToLine will no longer create an internal Point object, as it's not required internally (thanks @Trissolo)
  • The tempZone used by GridAlign has now had setOrigin(0, 0) applied to it. This leads to more accurate / expected zone placement when aligning grid items.
  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • When ImageFile loads with a linked Normal Map and the map completes first, but the Image is still in a pending state, it would incorrectly add itself to the cache instead of waiting. It now checks this process more carefully. Fix #5886 (thanks @inmylo)
  • Using a dataKey to specify a part of a JSON file when using load.pack would fail as it wouldn't correctly assign the right part of the pack file to the Loader. You can now use this parameter properly. Fix #6001 (thanks @rexrainbow)
  • The Text.advancedWordWrap function would incorrectly merge the current and next lines when wrapping words with carriage-returns in. Fix #6187 (thanks @Ariorh1337 @robinheidrich)
  • Recoded the point conversion math in the HexagonalTileToWorldXY function as it was incorrect. Now returns world coordinates correctly.
  • Tilemap.copy would error if you copied a block of tiles over itself, even partially, as it tried to copy already replaced tiles as part of the function. It will now copy correctly, regardless of source or destination areas. Fix #6188 (thanks @Arkyris)
  • Tile.copy will now use the DeepCopy function to copy the Tile.properties object, as otherwise it just gets copied by reference.
  • Recoded the point conversion math in the HexagonalWorldToTileXY function as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich)
  • Fixed the point conversion math in the IsometricWorldToTileXY function and added optional boolean property that allows the setting of the tile origin to the top or base. Fix #5781 (thanks @benjamin-wilson)
  • Calling Tilemap.worldToTileX or worldToTileY on a Isometric or Hexagonal Tilemap will now always return null instead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should use worldToTileXY instead.
  • The Game.headlessStep method will now reset SceneManager.isProcessing before PRE_RENDER. This fixes issues in HEADLESS mode where the Scene Manager wouldn't process additionally added Scenes created after the Game had started. Fix #5872 #5974 (thanks @micsun-al @samme)
  • If Rope.setPoints was called with the exact same number of points as before, it wouldn't set the dirty flag, meaning the vertices were not updated on the next render (thanks @stupot)
  • Particle.fire will now check to see if the parent Emitter is set to follow a Game Object and if so, and if the x/y EmitterOps are spread ops, then it'll space the particles out based on the follower coordinates, instead of clumping them all together. Fix #5847 (thanks @sreadixl)
  • When using RTL (right-to-left) Text Game Objects, the Text would vanish on iOS15+ if you changed the text or font style. The context RTL properties are now restored when the text is updated, fixing this issue. Fix #6121 (thanks @liorGameDev)
  • The InputPlugin.sortGameObjects method was using the Camera Render List to determine the Game Object display list. This would exclude non-rendering objects, such as Game Objects with alpha set to zero, even if their Input alwaysEnable flag was set. This method now uses the Display List instead, which gives correct results for invisible 'always enabled' objects. Fix #5507 (thanks @EmilSV)
  • The Tilemap.destroyLayer method would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme)
  • MapData and ObjectLayer will now enforce that the Tilemap.objects property is always an array. Sometimes Tiled willl set it to be a blank object in the JSON data. This fix makes sure it is always an array. Fix #6139 (thanks @robbeman)
  • The ParseJSONTiled function will now run a DeepCopy on the source Tiled JSON, which prevents object mutation, fixing an issue where Tiled Object Layer names would be duplicated if used across multiple Tilemap instances. Fix #6212 (thanks @temajm @wahur666)
  • The method Color.setFromHSV would not change the members h, s and v, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow)
  • When calling GameObject.getPostPipeline and passing in a string for the pipeline name it would error with 'Uncaught TypeError: Right-hand side of 'instanceof' is not an object'. This is now handled correctly internally (thanks @neki-dev)
  • When playing a chained animation, the nextAnim property could get set to undefined which would stop the next animation in the queue from being set. The check now handles all falsey cases. Fix #5852 (thanks @Pythux)
  • When calling InputPlugin.clear it will now call removeDebug on the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton)
  • The Video.loadURL method wouldn't load the video or emit the VIDEO_CREATED event unless noAudio was specified. A load event handler has been added to resolve this (thanks @samme)
  • If you create a repeating or looping TimerEvent with a delay of zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan)
  • The endFrame and startFrame properties of the SpriteSheet parser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the given startFrame so that is frame zero and end at endFrame, regardless how many other frames are in the sheet.
  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)
  • Sprites created directly (not via the Game Object Factory) which are then added to a Container would fail to play their animations, because they were not added to the Scene Update List. Fix #5817 #5818 #6052 (thanks @prakol16 @adomas-sk)
  • Game Objects that were created and destroyed (or moved to Containers) in the same frame were not correctly removed from the UpdateList. Fix #5803 (thanks @samme)
  • Container.removeHandler now specifies the context for Events.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would cause sys reference errors. Fix 5846 (thanks @sreadixl)
  • Container.removeAll (which is also called when a Container is destroyed) will now directly destroy the children, if the given parameter is set, rather than doing it after removing them via the event handler. This fixes an issue where nested Containers would add destroyed children back to the Scene as part of their shutdown process. Fix #6078 (thanks @BenoitFreslon)
  • The DisplayList.addChildCallback method will now check to see if the child has a parent container, and if it does, remove it from there before adding it to the Scene Display List. Fix #6091 (thanks @michalfialadev)
  • Display.RGB.equals will now return the correct result. Previously, it would always return false (thanks @samme)
  • When destroying the Arcade Physics World it will now destroy the debug Graphics object, had one been created. Previously, these would continue to stack-up should you restart the physics world (thanks @samme)
  • Graphics.strokeRoundedRect would incorrectly draw the rectangle if you passed in a radius greater than half of the smaller side. This is now clamped internally (thanks @temajm)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@201flaviosilva @AlbertMontagutCasero @Arcanorum @arosemena @austinlyon @chrisl8 @christian-post @danfoster @darrylpizarro @DeweyHur @ef4 @eltociear @EsteFilipe @etherealmachine @Fake @florestankorp @hacheraw @hanzooo @jerricko @joegaffey @jonasrundberg @kootoopas @lolimay @michalfialadev @monteiz @necrokot @Nero0 @orjandh @PhaserEditor2D @Pythux @quocsinh @rgk @rollinsafary-inomma @rstanuwijaya @samme @Smirnov48 @steveja42 @sylvainpolletvillard @twoco @ubershmekel @VanaMartin @vforsh @Vidminas @x-wk @xmahle @xuxucode @YeloPartyHat FromChris Golen OmniOwl

- JavaScript
Published by photonstorm over 3 years ago

phaser - Phaser v3.60 Beta 15

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

  • The RenderTarget class will now create a Framebuffer that includes a Depth Stencil Buffer attachment by default. Previously, it didn't. By attaching a stencil buffer it allows things like Geometry Masks to work in combination with Post FX and other Pipelines. Fix #5802 (thanks @mijinc0)
  • When calling PipelineManager.clear and rebind it will now check if the vao extension is available, and if so, it'll bind a null vertex array. This helps clean-up from 3rd party libs that don't do this directly, such as ThreeJS.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • The batchLine method in the Multi Pipeline will now check to see if the dxdy len is zero, and if so, it will abort drawing the line. This fixes issues on older Android devices, such as the Samsung Galaxy S6 or Kindle 7, where it would draw erroneous lines leading up to the top-left of the canvas under WebGL when rendering a stroked rounded rectangle. Fix #5429 (thanks @fkoch-tgm @sreadixl)
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light fragment shader will now use the outTintEffect attribute meaning the Light Pipeline will now correctly light both tinted and fill-tinted Game Objects. Fix #5452 (thanks @kainage)
  • The Light Pipeline will now check to see if a Light2D enabled Game Object has a parent Container, or not, and factor the rotation and scale of this into the light calculation. Fix #6086 (thanks @irongaze)
  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been rewritten to help with performance, resolve some of its lingering issues and unifies the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • The Tween.seek method used to take a value between 0 and 1, based on how far through the Tween you wished to seek. However, it did not work with infinitely looping or repeating Tweens and would crash the browser tab. The new seek method takes a value in milliseconds instead and works perfectly on infinite Tweens.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as the source for a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • origin is now (0.5, 0.5) by default instead of (0, 0).

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.
  • The GameObjects.Components.Mask.createBitmapMask method can now accept the x, y, texture and frame parameters new to the BitmapMask constructor.
  • Previously, calling createBitmapMask on a Shape Game Object would fail unless you passed the shape to the method. Now, it will correctly create a mask from the Shape without needing to pass it. Fix #5976 (thanks @samme)

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • The Tilemap and TilemapLayer classes have a new method getTileCorners. This method will return an array of Vector2s with each entry corresponding to the corners of the requested tile, in world space. This currently works for Orthographic and Hexagonal tilemaps.
  • BaseSoundManager.getAllPlaying is a new method that will return all currently playing sounds in the Sound Manager.
  • Animation.showBeforeDelay is a new optional boolean property you can set when creating, or playing an animation. If the animation has a delay before playback starts this controls if it should still set the first frame immediately, or after the delay has expired (the default).
  • InputPlugin.resetPointers is a new method that will loop through all of the Input Manager Pointer instances and reset them all. This is useful if a 3rd party component, such as Vue, has stolen input from Phaser and you need to reset its input state again.
  • Pointer.reset is a new method that will reset a Pointer instance back to its 'factory' settings.
  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • You can now optionally specify the maxSpeed value in the Arcade Physics Group config (thanks @samme)
  • You can now optionally specify the useDamping boolean in the Arcade Physics Group config (thanks @samme)
  • Removed the HexagonalTileToWorldY function as it cannot work without an X coordinate. Use HexagonalTileToWorldXY instead.
  • Removed the HexagonalWorldToTileY function as it cannot work without an X coordinate. Use HexagonalWorldToTileXY instead.
  • Earcut has been updated to version 2.2.4. This release improves performance by 10-15% and fixes 2 rare race conditions that could leave to infinite loops. Earcut is used internally by Graphics and Shape game objects when triangulating polygons for complex shapes.
  • The BaseSoundManager.getAll method used to require a key parameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned.
  • The WebAudioSoundManager will now detect if the Audio Context enters a 'suspended' or 'interrupted' state as part of its update loop and if so it'll try to resume the context. This can happen if you change or disable the audio device, such as plugging in headphones with built-in audio drivers then disconnecting them, or swapping tabs on iOS. Fix #5353 (thanks @helloyoucan)
  • The CONTEXT_RESTORED Game Event has been removed and the WebGL Renderer no longer listens for the contextrestored DOM event, or has a contextRestoredHandler method. This never actually worked properly, in any version of Phaser 3 - although the WebGLRenderer would be restored, none of the shaders, pipelines or textures were correctly re-created. If a context is now lost, Phaser will display an error in the console and all rendering will halt. It will no longer try to re-create the context, leading to masses of WebGL errors in the console. Instead, it will die gracefully and require a page reload.
  • The Text and TileSprite Game Objects no longer listen for the CONTEXT_RESTORED event and have had their onContextRestored methods removed.
  • Scenes.Systems.canInput is a new internal method that determines if a Scene can receive Input events, or not. This is now used by the InputPlugin instead of the previous isActive test. This allows a Scene to emit and handle input events even when it is running init or preload. Previously, it could only do this after create had finished running. Fix #6123 (thanks @yaasinhamidi)
  • The BitmapText Game Object has two new read-only properties displayWidth and displayHeight. This allows the BitmapText to correctly use the GetBounds component.
  • The BitmapText Game Object now has the GetBounds component added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames)
  • WebGLSnapshot will now flip the pixels in the created Image element if the source was a framebuffer. This means grabbing a snapshot from a Dynamic or Render Texture will now correctly invert the pixels on the y axis for an Image. Grabbing from the game renderer will skip this.
  • WebGLRenderer.snapshotFramebuffer and by extension, the snapshot methods in Dynamic Textures and Render Textures, has been updated to ensure that the width and height never exceed the framebuffer dimensions, or it'll cause a runtime error. The method snapshotArea has had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)
  • Animation.stop is always called when a new animation is loaded, regardless if the animation was playing or not and the delayCounter is reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)
  • ScaleManager.listeners has been renamed to domlisteners to avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)
  • Geom.Intersects.LineToLine will no longer create an internal Point object, as it's not required internally (thanks @Trissolo)
  • The tempZone used by GridAlign has now had setOrigin(0, 0) applied to it. This leads to more accurate / expected zone placement when aligning grid items.
  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • When ImageFile loads with a linked Normal Map and the map completes first, but the Image is still in a pending state, it would incorrectly add itself to the cache instead of waiting. It now checks this process more carefully. Fix #5886 (thanks @inmylo)
  • Using a dataKey to specify a part of a JSON file when using load.pack would fail as it wouldn't correctly assign the right part of the pack file to the Loader. You can now use this parameter properly. Fix #6001 (thanks @rexrainbow)
  • The Text.advancedWordWrap function would incorrectly merge the current and next lines when wrapping words with carriage-returns in. Fix #6187 (thanks @Ariorh1337 @robinheidrich)
  • Recoded the point conversion math in the HexagonalTileToWorldXY function as it was incorrect. Now returns world coordinates correctly.
  • Tilemap.copy would error if you copied a block of tiles over itself, even partially, as it tried to copy already replaced tiles as part of the function. It will now copy correctly, regardless of source or destination areas. Fix #6188 (thanks @Arkyris)
  • Tile.copy will now use the DeepCopy function to copy the Tile.properties object, as otherwise it just gets copied by reference.
  • Recoded the point conversion math in the HexagonalWorldToTileXY function as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich)
  • Fixed the point conversion math in the IsometricWorldToTileXY function and added optional boolean property that allows the setting of the tile origin to the top or base. Fix #5781 (thanks @benjamin-wilson)
  • Calling Tilemap.worldToTileX or worldToTileY on a Isometric or Hexagonal Tilemap will now always return null instead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should use worldToTileXY instead.
  • The Game.headlessStep method will now reset SceneManager.isProcessing before PRE_RENDER. This fixes issues in HEADLESS mode where the Scene Manager wouldn't process additionally added Scenes created after the Game had started. Fix #5872 #5974 (thanks @micsun-al @samme)
  • If Rope.setPoints was called with the exact same number of points as before, it wouldn't set the dirty flag, meaning the vertices were not updated on the next render (thanks @stupot)
  • Particle.fire will now check to see if the parent Emitter is set to follow a Game Object and if so, and if the x/y EmitterOps are spread ops, then it'll space the particles out based on the follower coordinates, instead of clumping them all together. Fix #5847 (thanks @sreadixl)
  • When using RTL (right-to-left) Text Game Objects, the Text would vanish on iOS15+ if you changed the text or font style. The context RTL properties are now restored when the text is updated, fixing this issue. Fix #6121 (thanks @liorGameDev)
  • The InputPlugin.sortGameObjects method was using the Camera Render List to determine the Game Object display list. This would exclude non-rendering objects, such as Game Objects with alpha set to zero, even if their Input alwaysEnable flag was set. This method now uses the Display List instead, which gives correct results for invisible 'always enabled' objects. Fix #5507 (thanks @EmilSV)
  • The Tilemap.destroyLayer method would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme)
  • MapData and ObjectLayer will now enforce that the Tilemap.objects property is always an array. Sometimes Tiled willl set it to be a blank object in the JSON data. This fix makes sure it is always an array. Fix #6139 (thanks @robbeman)
  • The ParseJSONTiled function will now run a DeepCopy on the source Tiled JSON, which prevents object mutation, fixing an issue where Tiled Object Layer names would be duplicated if used across multiple Tilemap instances. Fix #6212 (thanks @temajm @wahur666)
  • The method Color.setFromHSV would not change the members h, s and v, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow)
  • When calling GameObject.getPostPipeline and passing in a string for the pipeline name it would error with 'Uncaught TypeError: Right-hand side of 'instanceof' is not an object'. This is now handled correctly internally (thanks @neki-dev)
  • When playing a chained animation, the nextAnim property could get set to undefined which would stop the next animation in the queue from being set. The check now handles all falsey cases. Fix #5852 (thanks @Pythux)
  • When calling InputPlugin.clear it will now call removeDebug on the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton)
  • The Video.loadURL method wouldn't load the video or emit the VIDEO_CREATED event unless noAudio was specified. A load event handler has been added to resolve this (thanks @samme)
  • If you create a repeating or looping TimerEvent with a delay of zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan)
  • The endFrame and startFrame properties of the SpriteSheet parser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the given startFrame so that is frame zero and end at endFrame, regardless how many other frames are in the sheet.
  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)
  • Sprites created directly (not via the Game Object Factory) which are then added to a Container would fail to play their animations, because they were not added to the Scene Update List. Fix #5817 #5818 #6052 (thanks @prakol16 @adomas-sk)
  • Game Objects that were created and destroyed (or moved to Containers) in the same frame were not correctly removed from the UpdateList. Fix #5803 (thanks @samme)
  • Container.removeHandler now specifies the context for Events.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would cause sys reference errors. Fix 5846 (thanks @sreadixl)
  • Container.removeAll (which is also called when a Container is destroyed) will now directly destroy the children, if the given parameter is set, rather than doing it after removing them via the event handler. This fixes an issue where nested Containers would add destroyed children back to the Scene as part of their shutdown process. Fix #6078 (thanks @BenoitFreslon)
  • The DisplayList.addChildCallback method will now check to see if the child has a parent container, and if it does, remove it from there before adding it to the Scene Display List. Fix #6091 (thanks @michalfialadev)
  • Display.RGB.equals will now return the correct result. Previously, it would always return false (thanks @samme)
  • When destroying the Arcade Physics World it will now destroy the debug Graphics object, had one been created. Previously, these would continue to stack-up should you restart the physics world (thanks @samme)
  • Graphics.strokeRoundedRect would incorrectly draw the rectangle if you passed in a radius greater than half of the smaller side. This is now clamped internally (thanks @temajm)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@201flaviosilva @AlbertMontagutCasero @Arcanorum @arosemena @austinlyon @christian-post @danfoster @darrylpizarro @DeweyHur @ef4 @eltociear @EsteFilipe @etherealmachine @Fake @florestankorp @hacheraw @hanzooo @jerricko @joegaffey @jonasrundberg @kootoopas @lolimay @michalfialadev @monteiz @necrokot @Nero0 @orjandh @PhaserEditor2D @Pythux @quocsinh @rgk @rollinsafary-inomma @rstanuwijaya @samme @Smirnov48 @steveja42 @sylvainpolletvillard @twoco @ubershmekel @VanaMartin @vforsh @Vidminas @x-wk @xmahle @xuxucode @YeloPartyHat FromChris Golen OmniOwl

- JavaScript
Published by photonstorm over 3 years ago

phaser - Phaser v3.60.0 Beta 14

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light Pipeline will now check to see if a Light2D enabled Game Object has a parent Container, or not, and factor the rotation and scale of this into the light calculation. Fix #6086 (thanks @irongaze)
  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been rewritten to help with performance, resolve some of its lingering issues and unifies the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • The Tween.seek method used to take a value between 0 and 1, based on how far through the Tween you wished to seek. However, it did not work with infinitely looping or repeating Tweens and would crash the browser tab. The new seek method takes a value in milliseconds instead and works perfectly on infinite Tweens.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as the source for a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • origin is now (0.5, 0.5) by default instead of (0, 0).

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.
  • The GameObjects.Components.Mask.createBitmapMask method can now accept the x, y, texture and frame parameters new to the BitmapMask constructor.

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • Animation.showBeforeDelay is a new optional boolean property you can set when creating, or playing an animation. If the animation has a delay before playback starts this controls if it should still set the first frame immediately, or after the delay has expired (the default).
  • InputPlugin.resetPointers is a new method that will loop through all of the Input Manager Pointer instances and reset them all. This is useful if a 3rd party component, such as Vue, has stolen input from Phaser and you need to reset its input state again.
  • Pointer.reset is a new method that will reset a Pointer instance back to its 'factory' settings.
  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • Scenes.Systems.canInput is a new internal method that determines if a Scene can receive Input events, or not. This is now used by the InputPlugin instead of the previous isActive test. This allows a Scene to emit and handle input events even when it is running init or preload. Previously, it could only do this after create had finished running. Fix #6123 (thanks @yaasinhamidi)
  • The BitmapText Game Object has two new read-only properties displayWidth and displayHeight. This allows the BitmapText to correctly use the GetBounds component.
  • The BitmapText Game Object now has the GetBounds component added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames)
  • WebGLSnapshot will now flip the pixels in the created Image element if the source was a framebuffer. This means grabbing a snapshot from a Dynamic or Render Texture will now correctly invert the pixels on the y axis for an Image. Grabbing from the game renderer will skip this.
  • WebGLRenderer.snapshotFramebuffer and by extension, the snapshot methods in Dynamic Textures and Render Textures, has been updated to ensure that the width and height never exceed the framebuffer dimensions, or it'll cause a runtime error. The method snapshotArea has had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)
  • Animation.stop is always called when a new animation is loaded, regardless if the animation was playing or not and the delayCounter is reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)
  • ScaleManager.listeners has been renamed to domlisteners to avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)
  • Geom.Intersects.LineToLine will no longer create an internal Point object, as it's not required internally (thanks @Trissolo)
  • The tempZone used by GridAlign has now had setOrigin(0, 0) applied to it. This leads to more accurate / expected zone placement when aligning grid items.
  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • The method Color.setFromHSV would not change the members h, s and v, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow)
  • When calling GameObject.getPostPipeline and passing in a string for the pipeline name it would error with 'Uncaught TypeError: Right-hand side of 'instanceof' is not an object'. This is now handled correctly internally (thanks @neki-dev)
  • When playing a chained animation, the nextAnim property could get set to undefined which would stop the next animation in the queue from being set. The check now handles all falsey cases. Fix #5852 (thanks @Pythux)
  • When calling InputPlugin.clear it will now call removeDebug on the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton)
  • The Video.loadURL method wouldn't load the video or emit the VIDEO_CREATED event unless noAudio was specified. A load event handler has been added to resolve this (thanks @samme)
  • If you create a repeating or looping TimerEvent with a delay of zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan)
  • The endFrame and startFrame properties of the SpriteSheet parser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the given startFrame so that is frame zero and end at endFrame, regardless how many other frames are in the sheet.
  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)
  • Sprites created directly (not via the Game Object Factory) which are then added to a Container would fail to play their animations, because they were not added to the Scene Update List. Fix #5817 #5818 #6052 (thanks @prakol16 @adomas-sk)
  • Game Objects that were created and destroyed (or moved to Containers) in the same frame were not correctly removed from the UpdateList. Fix #5803 (thanks @samme)
  • Container.removeHandler now specifies the context for Events.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would cause sys reference errors. Fix 5846 (thanks @sreadixl)
  • Container.removeAll (which is also called when a Container is destroyed) will now directly destroy the children, if the given parameter is set, rather than doing it after removing them via the event handler. This fixes an issue where nested Containers would add destroyed children back to the Scene as part of their shutdown process. Fix #6078 (thanks @BenoitFreslon)
  • The DisplayList.addChildCallback method will now check to see if the child has a parent container, and if it does, remove it from there before adding it to the Scene Display List. Fix #6091 (thanks @michalfialadev)
  • Display.RGB.equals will now return the correct result. Previously, it would always return false (thanks @samme)
  • When destroying the Arcade Physics World it will now destroy the debug Graphics object, had one been created. Previously, these would continue to stack-up should you restart the physics world (thanks @samme)
  • Graphics.strokeRoundedRect would incorrectly draw the rectangle if you passed in a radius greater than half of the smaller side. This is now clamped internally (thanks @temajm)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@201flaviosilva @Arcanorum @arosemena @austinlyon @danfoster @darrylpizarro @DeweyHur @ef4 @eltociear @EsteFilipe @etherealmachine @Fake @florestankorp @hacheraw @hanzooo @jerricko @joegaffey @jonasrundberg @kootoopas @lolimay @michalfialadev @monteiz @necrokot @Nero0 @orjandh @PhaserEditor2D @Pythux @quocsinh @rgk @samme @Smirnov48 @sylvainpolletvillard @twoco @ubershmekel @VanaMartin @vforsh @x-wk @xmahle @xuxucode @YeloPartyHat Golen OmniOwl

- JavaScript
Published by photonstorm over 3 years ago

phaser - Phaser v3.60.0 Beta 13

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • If you have a customised Multi Tint Pipeline fragment shader that uses the %forloop% declaration, you should update it to follow the new format defined in Multi.frag. This new shader uses a function called getSampler instead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details.
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The WebGL.Utils.parseFragmentShaderMaxTextures function no longer supports the %forloop% declaration.
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been recoded to help with performance and resolving some of its lingering issues and unifying the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely ms/time based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • origin is now (0.5, 0.5) by default instead of (0, 0).

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • ScaleManager.listeners has been renamed to domlisteners to avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)
  • Geom.Intersects.LineToLine will no longer create an internal Point object, as it's not required internally (thanks @Trissolo)
  • The tempZone used by GridAlign has now had setOrigin(0, 0) applied to it. This leads to more accurate / expected zone placement when aligning grid items.
  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • When calling InputPlugin.clear it will now call removeDebug on the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton)
  • The Video.loadURL method wouldn't load the video or emit the VIDEO_CREATED event unless noAudio was specified. A load event handler has been added to resolve this (thanks @samme)
  • If you create a repeating or looping TimerEvent with a delay of zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan)
  • The endFrame and startFrame properties of the SpriteSheet parser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the given startFrame so that is frame zero and end at endFrame, regardless how many other frames are in the sheet.
  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)
  • Sprites created directly (not via the Game Object Factory) which are then added to a Container would fail to play their animations, because they were not added to the Scene Update List. Fix #5817 #5818 #6052 (thanks @prakol16 @adomas-sk)
  • Game Objects that were created and destroyed (or moved to Containers) in the same frame were not correctly removed from the UpdateList. Fix #5803 (thanks @samme)
  • Container.removeHandler now specifies the context for Events.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would cause sys reference errors. Fix 5846 (thanks @sreadixl)
  • Container.removeAll (which is also called when a Container is destroyed) will now directly destroy the children, if the given parameter is set, rather than doing it after removing them via the event handler. This fixes an issue where nested Containers would add destroyed children back to the Scene as part of their shutdown process. Fix #6078 (thanks @BenoitFreslon)
  • The DisplayList.addChildCallback method will now check to see if the child has a parent container, and if it does, remove it from there before adding it to the Scene Display List. Fix #6091 (thanks @michalfialadev)
  • Display.RGB.equals will now return the correct result. Previously, it would always return false (thanks @samme)
  • When destroying the Arcade Physics World it will now destroy the debug Graphics object, had one been created. Previously, these would continue to stack-up should you restart the physics world (thanks @samme)
  • Graphics.strokeRoundedRect would incorrectly draw the rectangle if you passed in a radius greater than half of the smaller side. This is now clamped internally (thanks @temajm)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@201flaviosilva @Arcanorum @arosemena @austinlyon @danfoster @darrylpizarro @DeweyHur @ef4 @eltociear @EsteFilipe @etherealmachine @Fake @florestankorp @hacheraw @hanzooo @jerricko @joegaffey @jonasrundberg @kootoopas @lolimay @michalfialadev @monteiz @necrokot @Nero0 @orjandh @PhaserEditor2D @Pythux @quocsinh @rgk @samme @Smirnov48 @sylvainpolletvillard @twoco @ubershmekel @VanaMartin @vforsh @x-wk @xmahle @xuxucode @YeloPartyHat Golen OmniOwl

- JavaScript
Published by photonstorm over 3 years ago

phaser - Phaser v3.60.0 Beta 12

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Vastly Improved Mobile Performance and WebGL Pipeline Changes

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • If you have a customised Multi Tint Pipeline fragment shader that uses the %forloop% declaration, you should update it to follow the new format defined in Multi.frag. This new shader uses a function called getSampler instead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details.
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The WebGL.Utils.parseFragmentShaderMaxTextures function no longer supports the %forloop% declaration.
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been recoded to help with performance and resolving some of its lingering issues and unifying the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely ms/time based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • Using DynamicTexture.fill in CANVAS mode only, after using the erase method, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik)
  • Drawing a frame via draw, drawFrame or batchDrawFrame and specifying a tint value would inverse the Red and Blue channels. These are now handled properly. Fix #5509 (thanks @anthonygood)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of a Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The Bitmap Mask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The Bitmap Mask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • When using Group.createMultiple it will now skip the post-creations options if they are not set in the config object used, or a Game Object constructor. Previously, things like alpha, position, etc would be over-written by the defaults if they weren't given in the config, but now the method will check to see if they are set and only use them if they are. This is a breaking change, but makes it more efficient and flexible (thanks @samme)
  • When running a Scene transition there is a new optional callback onStart, which is passed the parameters fromScene, toScene and duration allowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow)
  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • The GetBitmapTextSize function now includes an extra property in the resulting BitmapTextCharacter object called idx which is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH)
  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • The Video.loadURL method wouldn't load the video or emit the VIDEO_CREATED event unless noAudio was specified. A load event handler has been added to resolve this (thanks @samme)
  • If you create a repeating or looping TimerEvent with a delay of zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan)
  • The endFrame and startFrame properties of the SpriteSheet parser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the given startFrame so that is frame zero and end at endFrame, regardless how many other frames are in the sheet.
  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)
  • Sprites created directly (not via the Game Object Factory) which are then added to a Container would fail to play their animations, because they were not added to the Scene Update List. Fix #5817 #5818 #6052 (thanks @prakol16 @adomas-sk)
  • Game Objects that were created and destroyed (or moved to Containers) in the same frame were not correctly removed from the UpdateList. Fix #5803 (thanks @samme)
  • Container.removeHandler now specifies the context for Events.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would cause sys reference errors. Fix 5846 (thanks @sreadixl)
  • Container.removeAll (which is also called when a Container is destroyed) will now directly destroy the children, if the given parameter is set, rather than doing it after removing them via the event handler. This fixes an issue where nested Containers would add destroyed children back to the Scene as part of their shutdown process. Fix #6078 (thanks @BenoitFreslon)
  • The DisplayList.addChildCallback method will now check to see if the child has a parent container, and if it does, remove it from there before adding it to the Scene Display List. Fix #6091 (thanks @michalfialadev)
  • Display.RGB.equals will now return the correct result. Previously, it would always return false (thanks @samme)
  • When destroying the Arcade Physics World it will now destroy the debug Graphics object, had one been created. Previously, these would continue to stack-up should you restart the physics world (thanks @samme)
  • Graphics.strokeRoundedRect would incorrectly draw the rectangle if you passed in a radius greater than half of the smaller side. This is now clamped internally (thanks @temajm)

Examples, Documentation, Beta Testing and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Beta Testing, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur @twoco @austinlyon @Arcanorum OmniOwl @EsteFilipe @PhaserEditor2D @Fake @jonasrundberg @xmahle @arosemena @monteiz @VanaMartin @lolimay @201flaviosilva @orjandh @florestankorp @YeloPartyHat @hacheraw @kootoopas @joegaffey @rgk @ubershmekel @Nero0 @xuxucode @Smirnov48 @jerricko @ef4 @michalfialadev @darrylpizarro

- JavaScript
Published by photonstorm over 3 years ago

phaser - Phaser v3.60 Beta 11

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - New and Updated WebGL Pipelines

WebGL Renderer Updates

Due to all of the changes with how WebGL texture batching works a lot of mostly internal methods and properties have been removed. This is the complete list:

  • The WebGLRenderer.currentActiveTexture property has been removed.
  • The WebGLRenderer.startActiveTexture property has been removed.
  • The WebGLRenderer.tempTextures property has been removed.
  • The WebGLRenderer.textureZero property has been removed.
  • The WebGLRenderer.normalTexture property has been removed.
  • The WebGLRenderer.textueFlush property has been removed.
  • The WebGLRenderer.isTextureClean property has been removed.
  • The WebGLRenderer.setBlankTexture method has been removed.
  • The WebGLRenderer.setTextureSource method has been removed.
  • The WebGLRenderer.isNewNormalMap method has been removed.
  • The WebGLRenderer.setTextureZero method has been removed.
  • The WebGLRenderer.clearTextureZero method has been removed.
  • The WebGLRenderer.setNormalMap method has been removed.
  • The WebGLRenderer.clearNormalMap method has been removed.
  • The WebGLRenderer.unbindTextures method has been removed.
  • The WebGLRenderer.resetTextures method has been removed.
  • The WebGLRenderer.setTexture2D method has been removed.
  • The WebGLRenderer.pushFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.setFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.popFramebuffer method has had the resetTextures argument removed.
  • The WebGLRenderer.deleteTexture method has had the reset argument removed.
  • The Textures.TextureSource.glIndex property has been removed.
  • The Textures.TextureSource.glIndexCounter property has been removed.

Previously, WebGLRenderer.whiteTexture and WebGLRenderer.blankTexture had a data-type of WebGLTexture but they were actually Phaser.Textures.Frame instances. This has now been corrected and the two properties are now actually WebGLTexture instances, not Frames. If your code relies on this mistake being present, please adapt it.

Mobile Pipeline

  • The Mobile Pipeline is a new pipeline that extends the Multi Tint pipeline, but uses customized shaders and a single-bound texture specifically for mobile GPUs. This should restore mobile performance back to the levels it was around v3.22, before Multi Tint improved it all for desktop at the expense of mobile.
  • shaders/Mobile.vert and shaders/Mobile.frag are the two shaders used for the Mobile Pipeline.
  • PipelineManager#MOBILE_PIPELINE is a new constant-style reference to the Mobile Pipeline instance.
  • autoMobilePipeline is a new Game Configuration boolean that toggles if the Mobile Pipeline should be automatically deployed, or not. By default it is enabled, but you can set it to false to force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)
  • defaultPipeline is a new Game Configuration property that allows you to set the default Game Object Pipeline. This is set to Multi Tint as standard, but you can set it to your own pipeline from this value.
  • PipelineManager.default is a new propery that is used by most Game Objects to determine which pipeline they will init with.
  • PipelineManager.setDefaultPipeline is a new method that allows you to change the default Game Object pipeline. You could use this to allow for more fine-grained conditional control over when to use Multi or Mobile (or another pipeline)
  • The PipelineManager.boot method is now passed the default pipeline and auto mobile setting from the Game Config.

Multi Tint Pipeline

  • If you have a customised Multi Tint Pipeline fragment shader that uses the %forloop% declaration, you should update it to follow the new format defined in Multi.frag. This new shader uses a function called getSampler instead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details.
  • The Multi.frag shader now uses a highp precision, or mediump if the device doesn't support it (thanks @arbassic)
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The WebGL.Utils.parseFragmentShaderMaxTextures function no longer supports the %forloop% declaration.
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.
  • Previously, the Multi Tint methods batchSprite, batchTexture, batchTextureFrame and batchFillRect would all make heavy use of the TransformMatrix.getXRound and getYRound methods, which in turn called getX and getY and applied optional rounding to them. This is all now handled by one single function (setQuad) with no branching, meaning rendering one single sprite has cut down 16 function calls and 48 getters to just 1 function.

Lights Pipeline

  • The Light Pipeline no longer creates up to maxLights copies of the Light shader on boot. Previously it would then pick which shader to use, based on the number of visible lights in the Scene. Now, the number of lights is passed to the shader and branches accordingly. This means rather than compiling n shaders on boot, it now only ever needs to create one.
  • You can now have no lights in a Scene, but the Scene will still be impacted by the ambient light. Previously, you always needed at least 1 light to trigger ambient light (thanks jstnldrs)
  • The Light.frag shader now uses a new uLightCount uniform to know when to stop iterating through the max lights.
  • The LightPipeline.LIGHT_COUNT constant has been removed as it's not used internally.
  • The LightPipeline previous created a global level temporary vec2 for calculations. This is now part of the class as the new tempVec2 property.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been recoded to help with performance and resolving some of its lingering issues and unifying the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely ms/time based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

New Features - Dynamic Textures and Render Textures

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.

Before Phaser 3.60 this was known as a Render Texture. Dynamic Textures have been optimized and also offer the following new features and updates. All of these are also available to the new Render Texture, via the texture property:

  • TextureManager.addDynamicTexture(key, width, height) is a new method that will create a Dynamic Texture and store it in the Texture Manager, available globally for use by any Game Object.
  • Unlike the old Render Texture, Dynamic Texture extends the native Phaser.Texture class, meaning you can use it for any texture based object and also call all of the native Texture methods, such as the ability to add frames to it, use it as the backing source for a sprite sheet or atlas, and more.
  • Dynamic Textures no longer create both Render Targets and Canvas objects, only the one that they require based on the renderer. This means Render Textures and Dynamic Textures now use 50% less memory under WebGL and don't create Canvas DOM elements.
  • You can now directly use a Dynamic Texture as a Bitmap Mask.
  • Game Objects that have a mask will now reflect this when drawn to a Dynamic Texture.
  • DynamicTexture.isDrawing is a new boolean that allows you to tell if a batch draw has been started and is in process.
  • DynamicTexture.isSpriteTexture is a new boolean that informs the texture if it is being used as a backing texture for Sprite Game Objects, or not. If it is (which is the default) then items drawn to the texture are automatically inversed. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • DynamicTexture.setIsSpriteTexture is a new method that allows you to toggle the isSpriteTexture property in a chained manner.
  • DynamicTexture.renderTarget is a new property that holds an instance of a RenderTarget under WebGL. This encompasses a framebuffer and backing texture, rather than having them split.
  • DynamicTexture.stamp is a new method that takes a given texture key and then stamps it at the x/y coordinates provided. You can also pass in a config object that gives a lot more control, such as alpha, tint, angle, scale and origin of the stamp. This is a much cleaner way of stamping a texture to the DynamicTexture without having to first turn it into a Game Object.
  • DynamicTexture.repeat is a new method that will take a given texture and draw it to the Dynamic Texture as a fill-pattern. You can control the offset, width, height, alpha and tint of the draw (thanks xlapiz)
  • batchGameObject now splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.
  • The snapshot and snapshotPixel methods now use the snapshotArea method to reduce code and filesize.
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • DynamicTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • Using DynamicTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)

Due to the creation of the Dynamic Texture class, we have completely revamped the old Render Texture Game Object. This is now a combination of Dynamic Texture and an Image Game Object, that uses the Dynamic Texture to display itself with.

In versions of Phaser before 3.60 a Render Texture was the only way you could create a texture like this, that had the ability to be drawn on. But in 3.60 we split the core functions out to the Dynamic Texture class as it made a lot more sense for them to reside in there. As a result, the Render Texture is now a light-weight shim that sits on-top of an Image Game Object and offers proxy methods to the features available from a Dynamic Texture.

Render Texture breaking changes:

  • Render Textures used to be able to take key and frame arguments in their constructors, which would take the texture from the Texture Manager and use that instance, instead of creating a new one. Because Dynamic Textures are always stored in the Texture Manager from the beginning, there is no need to specify these arguments. You can just get it from the Texture Manager by using its key.

  • The following RenderTexture properties have changed:

  • renderer is now available via texture.renderer.

  • textureManager has been removed.

  • globalTint has been removed.

  • globalAlpha has been removed.

  • canvas is now available via texture.canvas.

  • context is now available via texture.context.

  • dirty is now available via texture.dirty.

  • camera is now available via texture.camera.

  • renderTarget is now available via texture.renderTarget.

  • The following RenderTexture methods have changed:

  • drawGameObject has been removed, this is now handled by the batch methods.

  • resize has been renamed. Use setSize(width, height) instead.

  • setGlobalTint has been removed as it's no longer used internally.

  • setGlobalAlpha has been removed as it's no longer used internally.

  • batchGameObjectWebGL has been removed, now handled by batchGameObject.

  • batchGameObjectCanvas has been removed, now handled by batchGameObject.

When should you use a Render Texture vs. a Dynamic Texture?

You should use a Dynamic Texture if the texture is going to be used by multiple Game Objects, or you want to use it across multiple Scenes, because textures are globally stored.

You should use a Dynamic Texture if the texture isn't going to be displayed in-game, but is instead going to be used for something like a mask or shader.

You should use a Render Texture if you need to display the texture in-game on a single Game Object, as it provides the convenience of wrapping an Image and Dynamic Texture together for you.

Bitmap Mask Updates

There are breaking changes from previous versions of Phaser.

  • Previously, every unique Bitmap Mask would create two full renderer sized framebuffers and two corresponding WebGL textures for them. The Bitmap Mask would listen for resize events from the renderer and then re-create these framebuffers accordingly. However, as the Bitmap Mask pipeline would clear and re-render these framebuffers every single frame it made no sense to have them use such large amounts of GPU memory. As of 3.60, the WebGL Renderer creates and manages two RenderTargets which all Bitmap Masks now use. If you previously used multiple Bitmap Masks in your game this change will dramatically reduce memory consumption at no performance cost.
  • The BitmapMask constructor is now capable of creating an Image Game Object from the new optional arguments: x, y, texture, frame if no masked object is provided.
  • The BitmapMask now registers itself with the Game Object Factory. This means you can do this.add.bitmapMask() from within a Scene, for easier creation.
  • Due to the change in ownership of the framebuffers, the following properties have been removed from the BitmapMask class: renderer, maskTexture, mainTexture, dirty, mainFramebuffer and maskFramebuffer. The following methods have also been removed: createMask and clearMask.
  • The WebGLRenderer has 2 new properties: maskSource and maskTarget. These are the new global mask framebuffers.
  • WebGLRenderer.beginBitmapMask is a new method that starts the process of using the mask target framebuffer for drawing. This is called by the BitmapMaskPipeline.
  • WebGLRenderer.drawBitmapMask is a new method that completes the process of rendering using the mask target framebuffer. This is called by the BitmapMaskPipeline.
  • The BitmapMaskPipeline now hands over most control of the framebuffers to the WebGLRenderer.

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • TextureManager.silentWarnings is a new boolean property that, when set, will prevent the Texture Manager from emiting any warnings or errors to the console in the case of missing texture keys or invalid texture access. The default is to display these warnings, this flag toggles that.
  • TextureManager.parseFrame is a new method that will return a Texture Frame instance from the given argument, which can be a string, array, object or Texture instance.
  • GameConfig.stableSort and Device.features.stableSort is a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browser Array.sort. Only modern browsers have a stable Array.sort implementation, which Phaser requires. Older ones need to use our function instead. Set to 0 to use the legacy version, 1 to use the ES2019 version or -1 to have Phaser try and detect which is best for the browser (thanks @JernejHabjan)
  • Device.es2019 is a new boolean that will do a basic browser type + version detection to see if it supports ES2019 features natively, such as stable array sorting.
  • All of the following Texture Manager methods will now allow you to pass in a Phaser Texture as the source parameter: addSpriteSheet, addAtlas, addAtlasJSONArray, addAtlasJSONHash, addAtlasXML and addAtlasUnity. This allows you to add sprite sheet or atlas data to existing textures, or textures that came from external sources, such as SVG files, canvas elements or Dynamic Textures.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen, or the given Camera instance (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • Camera.isSceneCamera is a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via the Camera.setScene method. Once set the Camera.updateSystem method is skipped, preventing the WebGL Renderer from setting a scissor every frame.
  • Camera.preRender will now apply Math.floor instead of Math.round to the values, keeping it consistent with the Renderer when following a sprite.
  • When rendering a Sprite with a Camera set to roundPixels it will now run Math.floor on the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems.
  • TransformMatrix.setQuad is a new method that will perform the 8 calculations required to create the vertice positions from the matrix and the given values. The result is stored in the new TransformMatrix.quad Float32Array, which is also returned from this method.
  • TransformMatrix.multiply now directly updates the Float32Array, leading to 6 less getter invocations.
  • The CameraManager.getVisibleChildren method now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan)
  • SceneManager.systemScene is a new property that is set during the game boot and is a system Scene reference that plugins and managers can use, that lives outside of the Scene list.
  • The TextureManager.get methof can now accept a Frame instance as its parameter, which will return the frames parent Texture.
  • The GameObject.setFrame method can now accept a Frame instance as its parameter, which will also automatically update the Texture the Game Object is using.
  • Device.safariVersion is now set to the version of Safari running, previously it was always undefined.
  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The Display.Masks.BitmapMask destroy method will now remove the context-lost event handler.
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • BitmapMask.scene is a new property that allows the Bitmap Mask to reference the Scene it was created in.
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
  • The Texture.destroy method will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.

Bug Fixes

  • If you create a repeating or looping TimerEvent with a delay of zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan)
  • The endFrame and startFrame properties of the SpriteSheet parser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the given startFrame so that is frame zero and end at endFrame, regardless how many other frames are in the sheet.
  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)
  • Sprites created directly (not via the Game Object Factory) which are then added to a Container would fail to play their animations, because they were not added to the Scene Update List. Fix #5817 #5818 #6052 (thanks @prakol16 @adomas-sk)
  • Game Objects that were created and destroyed (or moved to Containers) in the same frame were not correctly removed from the UpdateList. Fix #5803 (thanks @samme)
  • Container.removeHandler now specifies the context for Events.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would cause sys reference errors. Fix 5846 (thanks @sreadixl)
  • Container.removeAll (which is also called when a Container is destroyed) will now directly destroy the children, if the given parameter is set, rather than doing it after removing them via the event handler. This fixes an issue where nested Containers would add destroyed children back to the Scene as part of their shutdown process. Fix #6078 (thanks @BenoitFreslon)
  • The DisplayList.addChildCallback method will now check to see if the child has a parent container, and if it does, remove it from there before adding it to the Scene Display List. Fix #6091 (thanks @michalfialadev)
  • Display.RGB.equals will now return the correct result. Previously, it would always return false (thanks @samme)
  • When destroying the Arcade Physics World it will now destroy the debug Graphics object, had one been created. Previously, these would continue to stack-up should you restart the physics world (thanks @samme)
  • Graphics.strokeRoundedRect would incorrectly draw the rectangle if you passed in a radius greater than half of the smaller side. This is now clamped internally (thanks @temajm)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur @twoco @austinlyon @Arcanorum OmniOwl @EsteFilipe @PhaserEditor2D @Fake @jonasrundberg @xmahle @arosemena @monteiz @VanaMartin @lolimay @201flaviosilva @orjandh @florestankorp @YeloPartyHat @hacheraw @kootoopas @joegaffey @rgk @ubershmekel @Nero0 @xuxucode @Smirnov48 @jerricko

- JavaScript
Published by photonstorm over 3 years ago

phaser - Phaser v3.60 Beta 10

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

Development of this feature was kindly sponsored by Club Penguin Rewritten (https://cprewritten.net).

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Multi Tint Pipeline

  • If you have a customised Multi Tint Pipeline fragment shader that uses the %forloop% declaration, you should update it to follow the new format defined in Multi.frag. This new shader uses a function called getSampler instead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details.
  • The Multi.frag shader now uses a highp precision instead of mediump.
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The WebGL.Utils.parseFragmentShaderMaxTextures function no longer supports the %forloop% declaration.
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.

Removed - Graphics Pipeline

The WebGL Graphics Pipeline has been removed. This pipeline wasn't used in v3.55, as all Graphics rendering is handled by the MultiTint pipeline, for better batching support. No Phaser Game Objects use the Graphics pipeline any longer, so to save space it has been removed and is no longer installed by the Pipeline Manager.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features - New Tween Manager

TODO - TweenData to class TODO - TweenData and Tween State methods TODO - CONST removals

The Phaser 3.60 Tween system has been recoded to help with performance and resolving some of its lingering issues and unifying the Tween events and callbacks.

The following are breaking changes:

  • Tween Timelines have been removed entirely. Due to the way they were implemented they tended to cause a range of esoteric timing bugs which were non-trivial to resolve. To that end, we made the decision to remove Timelines entirely and introduced the ability to chain tweens together using the new chain method. This should give most developers the same level of sequencing they had using Timelines, without the timing issues.
  • When creating a Tween, you can no longer pass a function for the following properties: duration, hold, repeat and repeatDelay. These should be numbers only. You can, however, still provide a function for delay, to keep it compatible with the StaggerBuilder.
  • The TweenManager#getAllTweens method has been renamed to TweenManager#getTweens. Functionally, it is the same.
  • The property and feature Tween.useFrames has been removed and is no longer a valid Tween Config option. Tweens are now entirely ms/time based.
  • The TweenOnUpdateCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onUpdateParams array when the Tween was created.
  • The TweenOnYoyoCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onYoyoParams array when the Tween was created.
  • The TweenOnRepeatCallback now has the following parameters: tween, targets, key (the property being tweened), current (the current value of the property), previous (the previous value of the property) and finally any of the params that were passed in the onRepeatParams array when the Tween was created.
  • Tween.stop has had the resetTo parameter removed from it. Calling stop on a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, see Tween.pause instead.
  • Tweens will now be automatically destroyed by the Tween Manager upon completion. This helps massively in reducing stale references and memory consumption. However, if you require your Tween to live-on, even after playback, then you can now specify a new persists boolean flag when creating it, or toggle the Tween.persist property before playback. This will force the Tween to not be destroyed by the Tween Manager, allowing you to replay it at any later point. The trade-off is that you are now entirely responsible for destroying the Tween when you are finished with it, in order to free-up resources.
  • All of the 'Scope' tween configuration callback properties have been removed, including onActiveScope, onCompleteScope, onLoopScope, onPauseScope, onRepeatScope, onResumeScope, onStartScope, onStopScope, onUpdateScope and onYoyoScope. You should set the callbackScope property instead, which will globally set the scope for all callbacks. You can also set the Tween.callbackScope property.

The following are to do with the new Chained Tweens feature:

  • TweenManager.chain - TODO

  • Tween.getChainedTweens is a new method that will return all of the tweens in a chained sequence, starting from the point of the Tween this is called on.

  • TweenManager.getChainedTweens(tween) is a new method that will return all of the tweens in a chained sequence, starting from the given tween.

  • You can now specify a target property as 'random' to have the Tween pick a random float between two given values, for example: alpha: 'random(0.25, 0.75)'. If you wish to force it to select a random integer, use 'int' instead: x: 'int(300, 600)'.

The following are further updates within the Tween system:

  • TweenManager.add and TweenManager.create can now optionally take an array of Tween Configuration objects. Each Tween will be created, added to the Tween Manager and then returned in an array. You can still pass in a single config if you wish.
  • Tween.pause is a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire the onPause callback.
  • Tween.resume is a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire the onResume callback.
  • There is a new TweenOnPauseCallback available when creating a Tween (via the onPause property). This comes with associated onPauseParams and onPauseScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you pause the Tween.
  • There is a new TweenOnResumeCallback available when creating a Tween (via the onResume property). This comes with associated onResumeParams and onResumeScope properties, too, like all other callbacks and can also be added via the Tween.setCallbacks method. This callback is invoked if you resume a previously paused Tween.
  • The property value of a Tween can now be an array, i.e. x: [ 100, 300, 200, 600 ] in which case the Tween will use interpolation to determine the value.
  • You can now specify an interpolation property in the Tween config to set which interpolation method the Tween will use if an array of numeric values have been given as the tween value. Valid values includes linear, bezier and catmull (or catmullrom), or you can provide your own function to use.
  • You can now specify a scale property in a Tween config and, if the target does not have a scale property itself (i.e. a GameObject) then it will automatically apply the value to both scaleX and scaleY together during the tween. This is a nice short-cut way to tween the scale of Game Objects by only specifying one property, instead of two.
  • killTweensOf(targets) now supports deeply-nested arrays of items as the target parameter. Fix #6016 (thanks @michalfialadev)
  • killTweensOf(target) did not stop target tweens if called immediately after tween creation. Fix #6173 (thanks @michalfialadev)
  • It wasn't possible to resume a Tween that was immediately paused after creation. Fix #6169 (thanks @trynx)
  • Calling Tween.setCallback() without specifying the params argument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio)
  • Calling Tween.play immediately after creating a tween with paused: true in the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab)
  • Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager timeScale value unless they were using frame-based timing instead of delta timing.
  • The first parameter to Tween.seek, toPosition now defaults to zero. Previously, you had to specify a value.
  • The TweenBuilder now uses the new GetInterpolationFunction function internally.
  • The TweenBuilder has been optimized to perform far less functions when creating the TweenData instances.
  • The keyword interpolation has been added to the Reserved Words list and Defaults list (it defaults to null).
  • The keyword persists has been added to the Reserved Words list and Defaults list (it defaults to false).
  • Tween.initTweenData is a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in the init and seek methods previously. This is called automatically and should not usually be invoked directly.
  • The internal Tween.calcDuration method has been removed. This is now handled as part of the initTweenData call.
  • Fixed a bug where setting repeat and hold would cause the Tween to include one final hold before marking itself as complete. It now completes as soon as the final repeat concludes, not after an addition hold.

TimeStep Updates

  • You can now enforce an FPS rate on your game by setting the fps: { limit: 30 } value in your game config. In this case, it will set an fps rate of 30. This forces Phaser to not run the game step more than 30 times per second (or whatever value you set) and works for both Request Animation Frame and SetTimeOut.
  • TimeStep._limitRate is a new internal private property allowing the Timestep to keep track of fps-limited steps.
  • TimeStep.hasFpsLimit is a new internal boolean so the Timestep knows if the step is fps rate limited, or not.
  • There is now a TimeStep.step method and TimeStep.setLimitFPS method. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically.
  • TimeStep.smoothDelta is a new method that encapsulates the delta smoothing.
  • TimeStep.updateFPS is a new method that calculates the moving frame rate average.
  • TimeStep.wake will now automatically reset the fps limits and internal update counters.
  • TimeStep.destroy will now call RequestAnimationFrame.destroy, properly cleaning it down.
  • RequestAnimationFrame.step will now no longer call requestAnimationFrame if isRunning has been set to false (via the stop method)
  • The TimeStep no longer calculates or passes the interpolation value to Game.step as it was removed several versions ago, so is redundant.
  • The RequestAnimationFrame.tick property has been removed as it's no longer used internally.
  • The RequestAnimationFrame.lastTime property has been removed as it's no longer used internally.
  • The RequestAnimationFrame class no longer calculates the tick or lastTime values and doesn't call performance.now as these values were never used internally and were not used by the receiving callback either.
  • The RequestAnimationFrame.target property has been renamed to delay to better describe what it does.
  • The TimeStep would always allocate 1 more entry than the deltaSmoothingMax value set in the game config. This is now clamped correctly (thanks @vzhou842)

New Features

  • The TextureManager.addSpriteSheet method will now allow you to pass in a Phaser Texture as the 2nd parameter. This allows you to add sprite sheet data to textures that came from external sources, such as SVG files or canvas elements.
  • Game.pause is a new method that will pause the entire game and all Phaser systems.
  • Game.resume is a new method that will resume the entire game and resume all of Phaser's systems.
  • RenderTexture.fillFrame is a new method that will take a given texture and draw it to the Render Texture as a fill-pattern. You can control the offset, alpha and tint of the draw (thanks xlapiz)
  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • RenderTexture.setIsSpriteTexture is a new method that allows you to flag a Render Texture as being used as the source for Sprite Game Object textures. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.
  • GameObjects.Polygon.setTo is a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)
  • maxAliveParticles is a new Particle Emitter config property that sets the maximum number of alive particles the emitter is allowed to update. When this limit is reached a particle will have to die before another can be spawned.
  • Utils.Array.Flatten is a new function that will return a flattened version of an array, regardless of how deeply-nested it is.
  • GameObjects.Text.appendText is a new method that will append the given text, or array of text, to the end of the content already stored in the Text object.
  • Textures.Events.ADD_KEY is a new event dispatched by the Texture Manager when a texture with the given key is added, allowing you to listen for the addition of a specific texture (thanks @samme)
  • Textures.Events.REMOVE_KEY is a new event dispatched by the Texture Manager when a texture with the given key is removed, allowing you to listen for the removal of a specific texture (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The Display.Masks.BitmapMask destroy method will now remove the context-lost event handler.
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • BitmapMask.scene is a new property that allows the Bitmap Mask to reference the Scene it was created in.
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.
  • If defined, the width and height of an input hit area will now be changed if the Frame of a Game Object changes. Fix #6144 (thanks @rexrainbow)
  • When passing a TextStyle configuration object to the Text Game Objects setStyle method, it would ignore any metrics data it may contain and reset it back to the defaults. It will now respect the metrics config and use it, if present. Fix #6149 (thanks @michalfialadev)
  • A Texture ScaleMode will now override the Game Config antialias setting under the Canvas Renderer, where-as before if antialias was true then it would ignore the scale mode of the texture (thanks @Cirras)
  • The Device.Audio module has been rewritten to use a new internal CanPlay function that cuts down on the amount of code required greatly.
  • Device.Audio.aac is a new boolean property that defines if the browser can play aac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • Device.Audio.flac is a new boolean property that defines if the browser can play flac audio files or not, allowing them to be loaded via the Loader (thanks @Ariorh1337)
  • The Physics.Arcade.Body.reset() method will now call Body.checkWorldBounds as part of the process, moving the body outside of the bounds, should you have positioned it so they overlap during the reset. Fix #5978 (thanks @lukasharing)
  • The temporary canvas created in CanvasFeatures for the checkInverseAlpha test is now removed from the CanvasPool after use.
  • The CanvasFeatures tests and the TextureManager _tempContext now specify the { willReadFrequently: true } hint to inform the browser the canvas is to be read from, not composited.
  • When calling TextureManager.getTextureKeys it will now exclude the default __WHITE texture from the results (thanks @samme)
  • If the WebGL Renderer logs an error, it will now show the error string, or the code if not present in the error map (thanks @zpxp)
  • The snapshotPixel function, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme)
  • The NoAudioSoundManager now has all of the missing methods, such as removeAll and get to allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)

Bug Fixes

  • Destroying a WebAudioSound in the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes. WebAudioSound will now bail out of its destroy sequence if it's already pending removal.
  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • RenderTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • Using RenderTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)
  • Sprites created directly (not via the Game Object Factory) which are then added to a Container would fail to play their animations, because they were not added to the Scene Update List. Fix #5817 #5818 #6052 (thanks @prakol16 @adomas-sk)
  • Game Objects that were created and destroyed (or moved to Containers) in the same frame were not correctly removed from the UpdateList. Fix #5803 (thanks @samme)
  • Container.removeHandler now specifies the context for Events.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would cause sys reference errors. Fix 5846 (thanks @sreadixl)
  • Container.removeAll (which is also called when a Container is destroyed) will now directly destroy the children, if the given parameter is set, rather than doing it after removing them via the event handler. This fixes an issue where nested Containers would add destroyed children back to the Scene as part of their shutdown process. Fix #6078 (thanks @BenoitFreslon)
  • The DisplayList.addChildCallback method will now check to see if the child has a parent container, and if it does, remove it from there before adding it to the Scene Display List. Fix #6091 (thanks @michalfialadev)
  • Display.RGB.equals will now return the correct result. Previously, it would always return false (thanks @samme)
  • When destroying the Arcade Physics World it will now destroy the debug Graphics object, had one been created. Previously, these would continue to stack-up should you restart the physics world (thanks @samme)
  • Graphics.strokeRoundedRect would incorrectly draw the rectangle if you passed in a radius greater than half of the smaller side. This is now clamped internally (thanks @temajm)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur @twoco @austinlyon @Arcanorum OmniOwl @EsteFilipe @PhaserEditor2D @Fake @jonasrundberg @xmahle @arosemena @monteiz @VanaMartin @lolimay @201flaviosilva

- JavaScript
Published by photonstorm over 3 years ago

phaser - Phaser v3.60 Beta 9

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

Development of this feature was kindly sponsored by Club Penguin Rewritten (https://cprewritten.net).

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Multi Tint Pipeline

  • If you have a customised Multi Tint Pipeline fragment shader that uses the %forloop% declaration, you should update it to follow the new format defined in Multi.frag. This new shader uses a function called getSampler instead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details.
  • The Multi.frag shader now uses a highp precision instead of mediump.
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The WebGL.Utils.parseFragmentShaderMaxTextures function no longer supports the %forloop% declaration.
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features

  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)
  • Experimental feature: The TilemapLayer now has the Mask component - meaning you can apply a mask to tilemaps (thanks @samme)
  • TilemapLayer.setTint is a new method that allows you to set the tint color of all tiles in the given area, optionally based on the filtering search options. This is a WebGL only feature.
  • RenderTexture.setIsSpriteTexture is a new method that allows you to flag a Render Texture as being used as the source for Sprite Game Object textures. You can also toggle the new boolean property isSpriteTexture as well. Doing this ensures that images drawn to the Render Texture are correctly inverted for rendering in WebGL. Not doing so can cause inverted frames. If you use this method, you must use it before drawing anything to the Render Texture. Fix #6057 #6017 (thanks @andymikulski @Grandnainconnu)
  • UtilityPipeline.blitFrame has a new optional boolean parameter flipY which, if set, will invert the source Render Target while drawing it to the destination Render Target.

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The Display.Masks.BitmapMask destroy method will now remove the context-lost event handler.
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • BitmapMask.scene is a new property that allows the Bitmap Mask to reference the Scene it was created in.
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)
  • You can now have a particle frequency smaller than the delta step, which would previously lead to inconsistencies in emission rates (thanks @samme)
  • The Light Game Object now has the Origin and Transform components, along with 4 new properties: width, height, displayWidth and displayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage)
  • The Transform Component has a new boolean read-only property hasTransformComponent which is set to true by default.
  • The Arcade Physics World.enableBody method will now only create and add a Body to an object if it has the Transform component, tested by checking the hasTransformComponent property. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail.
  • ProcessQueue.isActive is a new method that tests if the given object is in the active list, or not.
  • ProcessQueue.isPending is a new method that tests if the given object is in the pending insertion list, or not.
  • ProcessQueue.isDestroying is a new method that tests if the given object is pending destruction, or not.
  • ProcessQueue.add will no longer place the item into the pending list if it's already active or pending.
  • ProcessQueue.remove will check if the item is in the pending list, and simply remove it, rather than destroying it.
  • Container.addHandler will now call GameObject.addedToScene.
  • Container.removeHandler will now call GameObject.removedFromScene.

Bug Fixes

  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • RenderTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • Using RenderTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)
  • Sprites created directly (not via the Game Object Factory) which are then added to a Container would fail to play their animations, because they were not added to the Scene Update List. Fix #5817 #5818 #6052 (thanks @prakol16 @adomas-sk)
  • Game Objects that were created and destroyed (or moved to Containers) in the same frame were not correctly removed from the UpdateList. Fix #5803 (thanks @samme)
  • Container.removeHandler now specifies the context for Events.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would cause sys reference errors. Fix 5846 (thanks @sreadixl)
  • Container.removeAll (which is also called when a Container is destroyed) will now directly destroy the children, if the given parameter is set, rather than doing it after removing them via the event handler. This fixes an issue where nested Containers would add destroyed children back to the Scene as part of their shutdown process. Fix #6078 (thanks @BenoitFreslon)
  • The DisplayList.addChildCallback method will now check to see if the child has a parent container, and if it does, remove it from there before adding it to the Scene Display List. Fix #6091 (thanks @michalfialadev)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur @twoco @austinlyon @Arcanorum OmniOwl @EsteFilipe @PhaserEditor2D @Fake @jonasrundberg @xmahle @arosemena @monteiz @VanaMartin

- JavaScript
Published by photonstorm almost 4 years ago

phaser - Phaser v3.60 Beta 8

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

Development of this feature was kindly sponsored by Club Penguin Rewritten (https://cprewritten.net).

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Multi Tint Pipeline

  • If you have a customised Multi Tint Pipeline fragment shader that uses the %forloop% declaration, you should update it to follow the new format defined in Multi.frag. This new shader uses a function called getSampler instead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details.
  • The Multi.frag shader now uses a highp precision instead of mediump.
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The WebGL.Utils.parseFragmentShaderMaxTextures function no longer supports the %forloop% declaration.
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features

  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The Display.Masks.BitmapMask destroy method will now remove the context-lost event handler.
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • BitmapMask.scene is a new property that allows the Bitmap Mask to reference the Scene it was created in.
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)

Bug Fixes

  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • RenderTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • Using RenderTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur @twoco @austinlyon @Arcanorum OmniOwl @EsteFilipe @PhaserEditor2D @Fake @jonasrundberg @xmahle @arosemena @monteiz @VanaMartin

- JavaScript
Published by photonstorm about 4 years ago

phaser - Phaser v3.60 Beta 7

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

Development of this feature was kindly sponsored by Club Penguin Rewritten (https://cprewritten.net).

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Multi Tint Pipeline

  • If you have a customised Multi Tint Pipeline fragment shader that uses the %forloop% declaration, you should update it to follow the new format defined in Multi.frag. This new shader uses a function called getSampler instead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details.
  • The Multi.frag shader now uses a highp precision instead of mediump.
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The WebGL.Utils.parseFragmentShaderMaxTextures function no longer supports the %forloop% declaration.
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features

  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)
  • Vector2.project is a new method that will project the vector onto the given vector (thanks @samme)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.
  • LoaderPlugin.localSchemes is a new array of scheme strings that the Loader considers as being local files. This is populated by the new Phaser.Core.Config#loaderLocalScheme game / scene config property. It defaults to [ 'file://', 'capacitor://' ] but additional schemes can be defined or pushed onto this array. Based on #6010 (thanks @kglogocki)

Updates

  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The Display.Masks.BitmapMask destroy method will now remove the context-lost event handler.
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • BitmapMask.scene is a new property that allows the Bitmap Mask to reference the Scene it was created in.
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
  • When setting the Input Debug Hit Area color it was previously fixed to the value given when created. The value is now taken from the object directly, meaning you can set gameObject.hitAreaDebug.strokeColor in real-time (thanks @spayton)

Bug Fixes

  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • RenderTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • Using RenderTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)
  • Setting scale.mode in the Game Config would be ignored. It now accepts either this, or scaleMode directly. Fix #5970 (thanks @samme)
  • The frame duration calculations in the AnimationManager.createFromAseprite method would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello)
  • The TilemapLayer.getTilesWithinShape method would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme)
  • Modified the way Phaser uses require statements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09)
  • When creating a MatterTileBody from an isometric tile the tiles top value would be incorrect. The getTop method has been fixed to address this (thanks @adamazmil)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur @twoco @austinlyon @Arcanorum OmniOwl @EsteFilipe @PhaserEditor2D @Fake @jonasrundberg @xmahle @arosemena @monteiz @VanaMartin

- JavaScript
Published by photonstorm about 4 years ago

phaser - Phaser v3.60.0 Beta 6

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

Development of this feature was kindly sponsored by Club Penguin Rewritten (https://cprewritten.net).

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Multi Tint Pipeline

  • If you have a customised Multi Tint Pipeline fragment shader that uses the %forloop% declaration, you should update it to follow the new format defined in Multi.frag. This new shader uses a function called getSampler instead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details.
  • The Multi.frag shader now uses a highp precision instead of mediump.
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The WebGL.Utils.parseFragmentShaderMaxTextures function no longer supports the %forloop% declaration.
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features

  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)
  • You can now use dot notation as the datakey when defining a Loader Pack File (thanks @rexrainbow)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.

Updates

  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The Display.Masks.BitmapMask destroy method will now remove the context-lost event handler.
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • BitmapMask.scene is a new property that allows the Bitmap Mask to reference the Scene it was created in.
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
  • If you start a Scene that is already starting (START, LOADING, or CREATING) then the start operation is now ignored (thanks @samme)
  • If you start a Scene that is Sleeping, it is shut down before starting again. This matches how Phaser currently handles paused scenes (thanks @samme)
  • The right-click context menu used to be disabled on the document.body via the disableContextMenu function, but instead now uses the MouseManager / TouchManager targets, which if not specified defaults to the game canvas. Fix # (thanks @lukashass)
  • The Particle 'moveTo' calculations have been simplied and made more efficient (thanks @samme)
  • The Key.reset method no longer resets the Key.enabled or Key.preventDefault booleans back to true again, but only resets the state of the Key. Fix #6098 (thanks @descodifica)

Bug Fixes

  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • RenderTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)
  • Drawing Game Objects to a Render Texture in WebGL would skip their blend modes. This is now applied correctly. Fix #5565 #5996 (thanks @sjb933 @danarcher)
  • Loading a Script File Type will now default the 'type' property to 'script' when a type is not provided. Fix #5994 (thanks @samme @ItsGravix)
  • Using RenderTexture.fill in CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski)
  • If you Paused or Stopped a Scene that was in a preload state, it would still call 'create' after the Scene had shutdown (thanks @samme)
  • BitmapText rendering wouldn't correctly apply per-character kerning offsets. These are now implemented during rendering (thanks @arbassic)
  • Child Spine objects inside Containers wouldn't correctly inherit the parent Containers alpha. Fix #5853 (thanks @spayton)
  • The DisplayList will now enter a while loop until all Game Objects are destroyed, rather than cache the list length. This prevents "cannot read property 'destroy' of undefined" errors in Scenes. Fix #5520 (thanks @schontz @astei)
  • Particles can now be moved to 0x0. moveToX and moveToY now default to null instead of 0 (thanks @samme)
  • Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
  • An error in the GetBitmapTextSize function caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09)
  • WebGLSnapshot and CanvasSnapshot will now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)
  • ContainerCanvasRenderer would pass in a 5th container parameter to the child renderCanvas call, which was breaking the GraphicsCanvasRenderer and isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)
  • Fixed issue in Utils.Objects.GetValue where it would return an incorrect result if a source and altSource were provided that didn't match in structure. Fix #5952 (thanks @rexrainbow)
  • Fixed issue in Game Config where having an empty object, such as render: {} would cause set properties to be overriden with the default value. Fix #6097 (thanks @michalfialadev)
  • The SceneManager.moveAbove and moveBelow methods didn't check the order of the Scenes being moved, so moved them even if one was already above / below the other. Both methods now check the indexes first. Fix #6040 (thanks @yuupsup)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur @twoco @austinlyon @Arcanorum OmniOwl @EsteFilipe @PhaserEditor2D @Fake @jonasrundberg @xmahle @arosemena @monteiz

- JavaScript
Published by photonstorm about 4 years ago

phaser - Phaser v3.60.0 Beta 4

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

Development of this feature was kindly sponsored by Club Penguin Rewritten (https://cprewritten.net).

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Multi Tint Pipeline

  • If you have a customised Multi Tint Pipeline fragment shader that uses the %forloop% declaration, you should update it to follow the new format defined in Multi.frag. This new shader uses a function called getSampler instead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details.
  • The Multi.frag shader now uses a highp precision instead of mediump.
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The WebGL.Utils.parseFragmentShaderMaxTextures function no longer supports the %forloop% declaration.
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.

New Features - Matter Physics v0.18

We have updated the version of Matter Physics to the latest v0.18 release. This is a big jump and brings with it quite a few internal changes to Matter. The following are the differences we have identified in this release:

  • Up to ~40% performance improvement (on average measured over all examples, in Node on a Mac Air M1)
  • Replaces Matter.Grid with a faster and more efficient broadphase in Matter.Detector.
  • Reduced memory usage and garbage collection.
  • Resolves issues in Matter.SAT related to collision reuse.
  • Removes performance issues from Matter.Grid.
  • Improved collision accuracy.
  • MatterPhysics.collision is a new reference to the Collision module, which now handles all Matter collision events.
  • MatterPhysics.grid has been removed as this is now handled by the Collision module.
  • MatterPhysics.sat has been removed as this is now handled by the Collision module.
  • The Matter.Body.previousPositionImpulse property has been removed as it's no longer used.

New Features

  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)
  • TweenManager.reset is a new method that will take a tween, remove it from all internal arrays, then seek it back to its start and set it as being active.
  • The Video config will now detect for x-m4v playback support for video formats and store it in the Video.m4v property. This is used automatically by the VideoFile file loader. Fix #5719 (thanks @patrickkeenan)
  • The KeyboardPlugin.removeKey method has a new optional parameter removeCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree)
  • The KeyboardPlugin.removeAllKeys method has a new optional parameter removeCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin.
  • WebGLShader.fragSrc is a new property that holds the source of the fragment shader.
  • WebGLShader.vertSrc is a new property that holds the source of the vertex shader.
  • WebGLShader#.createProgram is a new method that will destroy and then re-create the shader program based on the given (or stored) vertex and fragment shader source.
  • WebGLShader.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • WebGLPipeline.setBoolean is a new method that allows you to set a boolean uniform on a shader.
  • Phaser.Scenes.Systems.getStatus is a new method that will return the current status of the Scene.
  • Phaser.Scenes.ScenePlugin.getStatus is a new method that will return the current status of the given Scene.
  • Math.LinearXY is a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)
  • Curves.Path.getCurveAt is a new method that will return the curve that forms the path at the given location (thanks @natureofcode)
  • You can now use any Shape Game Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow)
  • Mesh.setTint is a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.tint is a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)
  • Mesh.clearTint is a new method that will clear the tint from all vertices of a Mesh (thanks @rexrainbow)

Geom Updates

The following are API-breaking, in that a new optional parameter has been inserted prior to the output parameter. If you use any of the following functions, please update your code:

  • The Geom.Intersects.GetLineToLine method has a new optional parameter isRay. If true it will treat the first line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPoints method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • The Geom.Intersects.GetLineToPolygon method has a new optional parameter isRay. If true it will treat the line parameter as a ray, if false, as a line segment (the default).
  • Geom.Intersects.GetRaysFromPointToPolygon uses the new isRay parameter to enable this function to work fully again.

Loader Updates

  • MultiFile.pendingDestroy is a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits the FILE_COMPLETE and FILE_KEY_COMPLETE events, fixing a bug where MultiFile related files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit the filecomplete events for the parent file, only for the sub-files. This means you can now listen for the file completion event for multiatlas files, among others.
  • MultiFile.destroy is a new method that clears down all external references of the file, helping free-up resources.
  • File.addToCache no longer calls File.pendingDestroy, instead this is now handled by the Loader Plugin.
  • There is a new File constant FILE_PENDING_DESTROY which is used to ensure Files aren't flagged for destruction more than once.

Updates

  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The Display.Masks.BitmapMask destroy method will now remove the context-lost event handler.
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • BitmapMask.scene is a new property that allows the Bitmap Mask to reference the Scene it was created in.
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop and sleep will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
  • The ScriptFile Loader File Type has a new optional parameter: type. This is a string that controls the type attribute of the <script> tag that is generated by the Loader. By default it is 'script', but you can change it to 'module' or any other valid type.
  • The JSON Hash and Array Texture Parsers will now throw a console.warn if the JSON is invalid and contains identically named frames.
  • Scene.pause will now check to see if the Scene is in either a RUNNING or CREATING state and throw a warning if not. You cannot pause non-running Scenes.
  • Mesh.addVertices will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • Mesh.addVerticesFromObj will now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)
  • TouchManager.onTouchOver and onTouchOut have been removed, along with all of their related event calls as they're not used by any browser any more.
  • TouchManager.isTop is a new property, copied from the MouseManager, that retains if the window the touch is interacting with is the top one, or not.
  • The InputManager.onTouchMove method will now check if the changed touch is over the canvas, or not, via the DOM elementFromPoint function. This means if the touch leaves the canvas, it will now trigger the GAME_OUT and GAME_OVER events, where-as before this would only happen for a Mouse. If the touch isn't over the canvas, no Pointer touch move happens, just like with the mouse. Fix #5592 (thanks @rexrainbow)
  • TileMap.createBlankDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createDynamicLayer has now been removed as it was deprecated in 3.50.
  • TileMap.createStaticLayer has now been removed as it was deprecated in 3.50.
  • Animations.AnimationManager.createFromAseprite has a new optional 3rd parameter target. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)
  • Animations.AnimationState.createFromAseprite is a new method that allows you to create animations from exported Aseprite data directly on a Sprite, rather than always in the global Animation Manager (thanks Telemako)
  • The path package used by the TS Defs generator has been moved to devDependencies (thanks @antkhnvsk)
  • The GetValue function has a new optional parameter altSource which allows you to provide an alternative object to source the value from.
  • The Renderer.Snapshot.WebGL function has had its first parameter changed from an HTMLCanvasElement to a WebGLRenderingContext. This is now passed in from the snapshot methods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)

Bug Fixes

  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)
  • Calling ParticleEmitter.setScale would set the scaleY property to null, causing calls to setScaleY to throw a runtime error. scaleY is now a required property across both the Particle and Emitter classes and all of the conditional checks for it have been removed (thanks ojg15)
  • Calling Tween.reset when a tween was in a state of PENDING_REMOVE would cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton)
  • The default Tween._pausedState has changed from INIT to PENDING_ADD. This fixes a bug where if you called Tween.play immediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures)
  • If you start a PathFollower with a to value it will now tween and complete at that value, rather than the end of the path as before (thanks @samme)
  • Text with RTL enabled wouldn't factor in the left / right padding correctly, causing the text to be cut off. It will now account for padding in the line width calculations. Fix #5830 (thanks @rexrainbow)
  • The Path.fromJSON function would use the wrong name for a Quadratic Bezier curve class, meaning it would be skipped in the exported JSON. It's now included correctly (thanks @natureofcode)
  • The Input.Touch.TouchManager.stopListeners forgot to remove the touchcancel handler. This is now removed correctly (thanks @teng-z)
  • The BitmapMask shader has been recoded so it now works correctly if you mask a Game Object that has alpha set on it, or in its texture. Previously it would alpha the Game Object against black (thanks stever1388)
  • When the Pointer moves out of the canvas and is released it would trigger Uncaught TypeError: Cannot read properties of undefined (reading 'renderList') if multiple children existed in the pointer-out array. Fix #5867 #5699 (thanks @rexrainbow @lyger)
  • If the Input Target in the game config was a string, it wouldn't be correctly parsed by the Touch Manager.
  • The InputPlugin.sortGameObjects will now assign a value of 0 to any game object not in the render list, but still viable for input, such as an invisible object with alwaysEnabled set to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV)
  • The GameObject.willRender method will now factor in the parent displayList, if it has one, to the end result. This fixes issues like that where an invisible Layer will still process input events. Fix #5883 (thanks @rexrainbow)
  • InputPlugin.disable will now also reset the drag state of the Game Object as well as remove it from all of the internal temporary arrays. This fixes issues where if you disabled a Game Object for input during an input event it would still remain in the temporary internal arrays. This method now also returns the Input Plugin, to match enable. Fix #5828 (thank @natureofcode @thewaver)
  • The GetBounds component has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme)
  • SceneManager.moveAbove and moveBelow now take into account the modified indexes after the move (thanks @EmilSV)
  • When forcing a game to use setTimeout and then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski)
  • Including a render object within the Game Config will no longer erase any top-level config render settings. The render object will now take priority over the game config, but both will be used (thanks @vzhou842)
  • Calling Tween.stop(0) would run for an additional delta before stopping, causing the Tween to not be truly 100% "reset". Fix #5986 (thanks @Mesonyx)
  • The Utils.Array.SafeRange function would exclude valid certain ranges. Fix #5979 (thanks @ksritharan)
  • The "Skip intersects check by argument" change in Arcade Physics has been reverted. Fix #5956 (thanks @samme)
  • The Container.pointToContainer method would ignore the provided output parameter, but now uses it (thanks @vforsh)
  • The Polygon Game Object would ignore its closePath property when rendering in Canvas. Fix #5983 (thanks @optimumsuave)
  • IE9 Fix: Added 2 missing Typed Array polyfills (thanks @jcyuan)
  • IE9 Fix: CanvasRenderer ignores frames with zero dimensions (thanks @jcyuan)
  • RenderTexture.batchTextureFrame will now skip the drawImage call in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)
  • BlitterCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • ParticleManagerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • CanvasSnapshot will now skip the drawImage call in canvas if the frame width or height are zero.
  • TextureManager.getBase64 will now skip the drawImage call in canvas if the frame width or height are zero.
  • TilemapLayerCanvasRenderer will now skip the drawImage call in canvas if the frame width or height are zero.
  • Audio will now unlock properly again on iOS14 and above in Safari. Fix #5696 (thanks @laineus)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur @twoco @austinlyon @Arcanorum OmniOwl @EsteFilipe @PhaserEditor2D @Fake

- JavaScript
Published by photonstorm over 4 years ago

phaser - Phaser v3.60.0 Beta 3

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific propertis and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.
  • WebGLPipeline.flipProjectionMatrix is a new method that allows you to flip the y and bottom projection matrix values via a parameter.
  • PipelineManager.renderTargets is a new property that holds an array of RenderTarget objects that all SpriteFX pipelines can share, to keep texture memory as low as possible.
  • PipelineManager.maxDimension is a new property that holds the largest possible target dimension.
  • PipelineManager.frameInc is a new property that holds the amount the RenderTargets will increase in size in each iteration. The default value is 32, meaning it will create targets of size 32, 64, 96, etc. You can control this via the pipeline config object.
  • PipelineManager.targetIndex is a new property that holds the internal target array offset index. Treat it as read-only.
  • The Pipeline Manager will now create a bunch of RenderTarget objects during its boot method. These are sized incrementally from 32px and up (use the frameInc value to alter this). These targets are shared by all Sprite FX Pipelines.
  • PipelineManager.getRenderTarget is a new method that will return the a RenderTarget that best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.
  • PipelineManager.getSwapRenderTarget is a new method that will return a 'swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.
  • PipelineManager.getAltSwapRenderTarget is a new method that will return a 'alternative swap' RenderTarget that matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, or Multi Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these type of files.

Development of this feature was kindly sponsored by Club Penguin Rewritten (https://cprewritten.net).

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features - Multi Tint Pipeline

  • If you have a customised Multi Tint Pipeline fragment shader that uses the %forloop% declaration, you should update it to follow the new format defined in Multi.frag. This new shader uses a function called getSampler instead of the often massive if/else glsl blocks from before. Please see the shader code and update your own shaders accordingly.
  • The Multi.frag shader now uses a highp precision instead of mediump.
  • The WebGL.Utils.checkShaderMax function will no longer use a massive if/else glsl shader check and will instead rely on the value given in gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS).
  • The WebGL.Utils.parseFragmentShaderMaxTextures function no longer supports the %forloop% declaration.
  • The internal WebGL Utils function GenerateSrc has been removed as it's no longer required internally.

New Features

  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)

Updates

  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The Display.Masks.BitmapMask destroy method will now remove the context-lost event handler.
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • BitmapMask.scene is a new property that allows the Bitmap Mask to reference the Scene it was created in.
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
  • A new console.error will be printed if the File, MultiFile, JSONFile or XMLFile fail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)

Bug Fixes

  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.
  • ScaleManager.getParentBounds will now also check to see if the canvas bounds have changed x or y position, and if so return true, causing the Scale Manager to refresh all of its internal cached values. This fixes an issue where the canvas may have changed position on the page, but not its width or height, so a refresh wasn't triggered. Fix #5884 (thanks @jameswilddev)
  • The SceneManager.bootScene method will now always call LoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch its START and COMPLETE events, even if the queue is empty because the files are already cached. You can now rely on the START and COMPLETE events to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals)
  • Calling TimerEvent.reset in the Timer callback would cause the timer to be added to the Clock's pending removal and insertion lists together, throwing an error. It will now not add to pending removal if the timer was reset. Fix #5887 (thanks @rexrainbow)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur @twoco @austinlyon @Arcanorum

- JavaScript
Published by photonstorm over 4 years ago

phaser - Phaser 3.60.0 Beta 2

Version 3.60.0 - Miku - in development

New Features - Sprite FX

  • When defining the renderTargets in a WebGL Pipeline config, you can now set optional width and height properties, which will create a Render Target of that exact size, ignoring the scale value (if also given).
  • WebGLPipeline.isSpriteFX is a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default is false.
  • GameObjects.Components.FX is a new component that provides access to FX specific propertis and methods. The Image and Sprite Game Objects have this component by default.
  • fxPadding and its related method setFXPadding allow you to set extra padding to be added to the texture the Game Object renders with. This is especially useful for Sprite FX shaders that modify the sprite beyond its bounds, such as glow or shadow effects.
  • The WebGLPipeline.setShader method has a new optional parameter buffer that allows you to set the vertex buffer to be bound before the shader is activated.
  • The WebGLPipeline.setVertexBuffer method has a new optional parameter buffer that allows you to set the vertex buffer to be bound if you don't want to bind the default one.
  • The WebGLRenderer.createTextureFromSource method has a new optional boolean parameter forceClamp that will for the clamp wrapping mode even if the texture is a power-of-two.
  • RenderTarget will now automatically set the wrapping mode to clamp.

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these.

Development of this feature was kindly sponsored by Club Penguin Rewritten (https://cprewritten.net).

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features

  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang @kainage)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)

Updates

  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The Display.Masks.BitmapMask destroy method will now remove the context-lost event handler.
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • BitmapMask.scene is a new property that allows the Bitmap Mask to reference the Scene it was created in.
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)
  • Removed the Tint and Flip components from the Camera class. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.

Bug Fixes

  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)
  • Timers with very short delays (i.e. 1ms) would only run the callback at the speed of the frame update. It will now try and match the timer rate by iterating the calls per frame. Fix #5863 (thanks @rexrainbow)
  • The Text, TileSprite and RenderTexture Game Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur

- JavaScript
Published by photonstorm over 4 years ago

phaser - Phaser 3.60.0 Beta 1

Version 3.60.0 - Miku - in development

New Features - Compressed Texture Support

Phaser 3.60 contains support for Compressed Textures. It can parse both KTX and PVR containers and within those has support for the following formats: ETC, ETC1, ATC, ASTC, BPTC, RGTC, PVRTC, S3TC and S3TCSRB. Compressed Textures differ from normal textures in that their structure is optimized for fast GPU data reads and lower memory consumption. Popular tools that can create compressed textures include PVRTexTool, ASTC Encoder and Texture Packer.

Compressed Textures are loaded using the new this.load.texture method, which takes a texture configuration object that maps the formats to the files. The browser will then download the first file in the object that it knows it can support. You can also provide Texture Atlas JSON data, too, so you can use compressed texture atlases. Currently, Texture Packer is the best tool for creating these.

  • TextureSoure.compressionAlgorithm is now populated with the compression format used by the texture.
  • Types.Textures.CompressedTextureData is the new compressed texture configuration object type.
  • TextureManager.addCompressedTexture is a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return a Texture object than any Sprite can use.
  • Textures.Parsers.KTXParser is a new parser for the KTX compression container format.
  • Textures.Parsers.PVRParser is a new parser for the PVR compression container format.
  • The WebGLRenderer.compression property now holds a more in-depth object containing supported compression formats.
  • The WebGLRenderer.createTextureFromSource method now accepts the CompressedTextureData data objects and creates WebGL textures from them.
  • WebGLRenderer.getCompressedTextures is a new method that will populate the WebGLRenderer.compression object and return its value. This is called automatically when the renderer boots.
  • WebGLRenderer.getCompressedTextureName is a new method that will return a compressed texture format GLenum based on the given format.

New Features

  • ScaleManager.getViewPort is a new method that will return a Rectangle geometry object that matches the visible area of the screen (thanks @rexrainbow)
  • When starting a Scene and using an invalid key, Phaser will now raise a console warning informing you of this, instead of silently failing. Fix #5811 (thanks @ubershmekel)
  • GameObjects.Layer.addToDisplayList and removeFromDisplayList are new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)
  • GameObjects.Video.loadURL has a new optional 4th parameter crossOrigin. This allows you to specify a cross origin request type when loading the video cross-domain (thanks @rmartell)
  • You can now set loader.imageLoadType: "HTMLImageElement" in your Game Configuration and the Phaser Loader will use an Image Tag to load all images, rather than XHR and a Blob object which is the default. This is a global setting, so all file types that use images, such as Atlas or Spritesheet, will be changed via this flag (thanks @hanzooo)
  • You can now control the drawing offset of tiles in a Tileset using the new optional property Tileset.tileOffset (which is a Vector2). This property is set automatically when Tiled data is parsed and found to contain it. Fix #5633 (thanks @moJiXiang)
  • You can now set the alpha value of the Camera Flash effect before running it, where-as previously it was always 1 (thanks @kainage)
  • The Tilemap.createFromObjects method has been overhauled to support typed tiles from the Tiled Map Editor (https://doc.mapeditor.org/en/stable/manual/custom-properties/#typed-tiles). It will now also examine the Tileset to inherit properties based on the tile gid. It will also now attempt to use the same texture and frame as Tiled when creating the object (thanks @lackhand)

Updates

  • When you try to use a frame that is missing on the Texture, it will now give the key of the Texture in the console warning (thanks @samme)
  • The Display.Masks.BitmapMask destroy method will now remove the context-lost event handler.
  • The hitArea parameter of the GameObjects.Zone.setDropZone method is now optional and if not given it will try to create a hit area based on the size of the Zone Game Object (thanks @rexrainbow)
  • BitmapMask.scene is a new property that allows the Bitmap Mask to reference the Scene it was created in.
  • The DOMElement.preUpdate method has been removed. If you overrode this method, please now see preRender instead.
  • DOMElement.preRender is a new method that will check parent visibility and improve its behavior, responding to the parent even if the Scene is paused or the element is inactive. Dom Elements are also no longer added to the Scene Update List. Fix #5816 (thanks @prakol16 @samme)
  • Phaser 3 is now built with webpack 5 and all related packages have been updated.
  • Previously, an Array Matrix would enforce it had more than 2 rows. This restriction has been removed, allowing you to define and rotate single-row array matrices (thanks @andriibarvynko)
  • The Gamepad objects now have full TypeScript definitions thanks to @sylvainpolletvillard
  • Lots of configuration objects now have full TypeScript definitions thanks to @16patsle
  • Particle.fire will now throw an error if the particle has no texture frame. This prevents an uncaught error later when the particle fails to render. Fix #5838 (thanks @samme @monteiz)
  • ParticleEmitterManager.setEmitterFrames will now print out console warnings if an invalid texture frame is given, or if no texture frames were set. Fix #5838 (thanks @samme @monteiz)
  • SceneManager.stop will now ignore the call if the Scene has already been shut down, avoiding potential problems with duplicate event handles. Fix #5826 (thanks @samme)

Bug Fixes

  • Animation.createFromAseprite would calculate an incorrect frame duration if the frames didn't all have the same speed.
  • The URL scheme capacitor:// has been added to the protocol check to prevent malformed double-urls in some environments (thanks @consolenaut)
  • Removed Config.domBehindCanvas property as it's never used internally. Fix #5749 (thanks @iamallenchang)
  • dispatchTweenEvent would overwrite one of the callback's parameters. This fix ensures that Tween.setCallback now works consistently. Fix #5753 (thanks @andrei-pmbcn @samme)
  • The context restore event handler is now turned off when a Game Object is destroyed. This helps avoid memory leakage from Text and TileSprite Game Objects, especially if you consistently destroy and recreate your Game instance in a single-page app (thanks @rollinsafary-inomma @rexrainbow @samme)
  • When the device does not support WebGL, creating a game with the renderer type set to Phaser.WEBGL will now fail with an error. Previously, it would fall back to Canvas. Now it will not fall back to Canvas. If you require that feature, use the AUTO render type. Fix #5583 (thanks @samme)
  • The Tilemap.createFromObjects method will now correctly place both tiles and other objects. Previously, it made the assumption that the origin was 0x1 for all objects, but Tiled only uses this for tiles and uses 0x0 for its other objects. It now handles both. Fix #5789 (thanks @samme)
  • The CanvasRenderer.snapshotCanvas method used an incorrect reference to the canvas, causing the operation to fail. It will now snapshot a canvas correctly. Fix #5792 #5448 (thanks @rollinsafary-inomma @samme @akeboshi1)
  • The Tilemap.tileToWorldY method incorrectly had the parameter tileX. It will worked, but didn't make sense. It is now tileY (thanks @mayacoda)
  • The Tilemap.convertTilemapLayer method would fail for isometric tilemaps by not setting the physic body alignment properly. It will now call getBounds correctly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda)
  • The PluginManager.installScenePlugin method will now check if the plugin is missing from the local keys array and add it back in, if it is (thanks @xiamidaxia)
  • The Spine Plugin would not work with multiple instances of the same game on a single page. It now stores its renderer reference outside of the plugin, enabling this. Fix #5765 (thanks @xiamidaxia)
  • In Arcade Physics, Group vs. self collisions would cause double collision callbacks due to the use of the quad tree. For this specific conditions, the quad tree is now skipped. Fix #5758 (thanks @samme)
  • During a call to GameObject.Shapes.Rectangle.setSize it will now correctly update the Rectangle object's display origin and default hitArea (thanks @rexrainbow)
  • The Arcade Physics Body will now recalculate its center after separation with a Tile in time for the values to be correct in the collision callbacks (thanks @samme)
  • The ParseTileLayers function has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1)
  • The PutTileAt function will now set the Tile dimensions from the source Tileset, fixing size related issues when placing tiles manually. Fix #5644 (thanks @moJiXiang @stuffisthings)
  • The new Tileset.tileOffset property fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang)
  • Fixed issue in Geom.Intersects.GetLineToLine function that would fail with colinear lines (thanks @Skel0t)
  • The CameraManager.destroy function will now remove the Scale Manager RESIZE event listener created as part of boot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23)
  • With roundPixels set to true in the game or camera config, Sprites will no longer render at sub-pixel positions under CANVAS. Fix #5774 (thanks @samme)
  • The Camera will now emit PRE_RENDER and POST_RENDER events under the Canvas Renderer. Fix #5729 (thanks @ddanushkin)
  • The Multi Pipeline now uses highp float precision by default, instead of mediump. This fixes issues with strange blue 'spots' appearing under WebGL on some Android devices. Fix #5751 #5659 #5655 (thanks @actionmoon @DuncanPriebe @ddanushkin)
  • The Tilemaps.Tile.getBounds method would take a camera parameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle.
  • Tilemap.createFromObjects has had the rendering of Tiled object layers on isometric maps fixed. Objects contained in object layers generated by Tiled use orthogonal positioning even when the map is isometric and this update accounts for that (thanks @lfarroco)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@necrokot Golen @Pythux @samme @danfoster @eltociear @sylvainpolletvillard @hanzooo @etherealmachine @DeweyHur

- JavaScript
Published by photonstorm over 4 years ago

phaser - Phaser v3.55.2

Bug Fixes

  • Fixed an issue in FillPathWebGL, IsoBoxWebGLRenderer and IsoTriangleWebGLRenderer functions which caused the filled versions of most Shape Game Objects to pick-up the texture of the previous object on the display list. Fix #5720 (thanks @samme)

- JavaScript
Published by photonstorm about 5 years ago

phaser - Phaser v3.55.1

New Features

  • The GameObject.destroy method has a new fromScene parameter, set automatically by Phaser. Fix #5716 (thanks @rexrainbow)
  • The Game Object DESTROY event is now set the new fromScene boolean as the 2nd parameter, allowing you to determine what invoked the event (either user code or a Scene change). Fix #5716 (thanks @rexrainbow)

Bug Fixes

  • Fixed an issue with the TypeScript defs not recognising the Game Object Config properly. Fix #5713 (thanks @vforsh)
  • Fixed an issue in the FillPathWebGL function which caused the filled versions of the Arc, Circle, Ellipse, Polygon and Star Shapes to not render. Fix #5712 (thanks @rexrainbow)
  • Fixed rendering parameters in IsoBox and IsoTriangle Game Objects that stopped them from rendering correctly.
  • Added the missing WebGLPipelineUniformsConfig type def. Fix #5718 (thanks @PhaserEditor2D)

- JavaScript
Published by photonstorm about 5 years ago

phaser - Phaser v3.55.0

New Features

  • GameObjects.DOMElement.pointerEvents is a new property that allows you to set the pointerEvents attribute on the DOM Element CSS. This is auto by default and should not be changed unless you know what you're doing.
  • Core.Config.domPointerEvents is a new config property set via dom: { pointerEvents } within the Game Config that allows you to set the pointerEvents css attribute on the DOM Element container.
  • The RenderTexture.endDraw method has a new optional boolean erase which allows you to draw all objects in the batch using a blend mode of ERASE. This has the effect of erasing any filled pixels in the objects being drawn.
  • All of the methods from the GraphicsPipeline have now been merged with the MultiPipeline, these include batchFillRect, batchFillTriangle, batchStrokeTriangle, batchFillPath, batchStrokePath and batchLine. The Graphics Game Object and all of the Shape Game Objects have been updated to use the new Multi Pipeline. This means that drawing Sprites and Graphics / Shapes will all batch together again. Fix #5553 #5500 (thanks @venarius @roberthook823)

Updates

  • The types have been improved for WebGL Compressed Textures (thanks @vforsh)
  • Container.moveAbove is a new method that will move a Game Object above another in the same Container (thanks @rexrainbow)
  • Container.moveBelow is a new method that will move a Game Object below another in the same Container (thanks @rexrainbow)
  • List.moveAbove is a new method that will move a Game Object above another in the same List (thanks @rexrainbow)
  • List.moveBelow is a new method that will move a Game Object below another in the same List (thanks @rexrainbow)
  • The MeasureText function, as used by Text Game Objects, has had its performance enhanced by removing a duplicate image data check and also now checks for metrics properties correctly (thanks @valadaptive)
  • WebGLShader.setUniform1 has a new optional boolean parameter skipCheck which will force the function to set the values without checking against the previously held ones.
  • WebGLShader.setUniform2 has a new optional boolean parameter skipCheck which will force the function to set the values without checking against the previously held ones.
  • WebGLShader.setUniform3 has a new optional boolean parameter skipCheck which will force the function to set the values without checking against the previously held ones.
  • WebGLShader.setUniform4 has a new optional boolean parameter skipCheck which will force the function to set the values without checking against the previously held ones.
  • The WebGLShader.set1fv, set2fv, set3fv, set4fv, set1iv, set2iv, set3iv, set4iv, setMatrix2fv, setMatrix3fv and setMatrix4fv methods no longer try to do array comparisons when setting the uniforms, but sets them directly. Fix #5670 (thanks @telinc1)

Bug Fixes

  • Have reverted all of the DOM Element CSS changes back to how they were in 3.52, causing both DOM Input and Phaser Input to work together properly again. Fix #5628 (thanks @sacharobarts)
  • The Mesh Game Object would incorrectly cull faces if the Scene Camera scrolled. It now calculates the cull correctly, regardless of camera world position, zoom or rotation. Fix #5570 (thanks @hendrikras)
  • Math.ToXY will now return an empty Vector 2 if the index is out of range, where before it would return the input Vector2 (thanks @Trissolo)
  • The UpdateList.shutdown method will now remove the PRE_UPDATE handler from the ProcessQueue correctly (thanks @samme)
  • When loading a Video with a config object, it would not get the correct key value from it (thanks @mattjennings)
  • The GameObjectFactory.existing method will now accept Layer as a TypeScript type. Fix #5642 (thanks @michal-bures)
  • The Input.Pointer.event property can now be a WheelEvent as well.
  • Fixed an issue when loading audio files from a Phaser project wrapped in Capacitor native app shell on iOS (thanks @consolenaut)
  • Video would not resume playing after regaining focus swapping from another browser tab. Fix #5377 (thanks @spayton)
  • Container will now invoke addToRenderList before leaving the render method, fixing an issue with Container Input. Fix #5506 (thanks @vforsh @rexrainbow)
  • The Game.postBoot callback was never being invoked due to an incorrect internal property setter. Fix #5689 (thanks @sebastianfast)
  • The Light Game Object didn't set the shader uniforms correctly, causing it to appear to ignore image rotation with normal maps. Fix #5660 (thanks @sroboubi @telinc1)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@x-wk @samme @trynx @Palats @supertorpe @Pixelguy @Fractal @halgorithm @Golden @H0rn0chse @EmilSV @Patapits @karbassi

- JavaScript
Published by photonstorm about 5 years ago

phaser - Phaser v3.54.0

Version 3.54.0 - Futaro - 26th March 2021

New Features

  • Phaser.Math.Median is a new function that will calculate the median of the given values. The values are sorted and the middle value is returned. In case of an even number of values, the average of the two middle values is returned (thanks @vforsh)
  • ScenePlugin.pluginKey is a new string-based property, set by the PluginManager that contains the key of the plugin with the Scene Systems.

Updates

  • When the Scene-owned Input Plugin is shutdown (i.e. via a call to Scene.stop) it will now remove any Key objects that the plugin created, not just reset them. This is a quality-of-life breaking change from how it worked previously (thanks @veleek)
  • Thanks to a TS Parser update by @krotovic the JSDocs can now define @this tags. Fix #4669.
  • The Scenes.Systems.install method has been removed. It's no longer required and would throw an error if called. Fix #5580 (thanks @Trissolo)
  • The WebAudioSoundManager.onFocus method will now test to see if the state of the AudioContext is interrupted, as happens on iOS when leaving the page, and then resumes the context. Fix #5390 #5156 #4790 (thanks @SBCGames @micsun-al @AdamXA)

Bug Fixes

  • Adding a Game Object to a Container that already existed in another Container would leave a copy of it on the Display List. Fix #5618 (thanks Kromah @mariogarranz)
  • Fixed missing backgroundColor property in GameConfig. Fix #5597 (thanks @eli-s-r)
  • BitmapText wouldn't render correctly with the Canvas Renderer when the texture came from a Texture Atlas. Fix #5545 (thanks @vforsh)
  • #5504 had broken DOM Elements being able to be clicked due to an oversight of the DOM Container. DOM Elements now correctly pick-up the default pointer events handler. Fix #5594 (thanks @pizkaz)
  • The RGBToString function will no longer return CSS strings with decimal places if the input contained them (thanks @neil-h)
  • Objects added to a SpineContainer were also added to the base Display List, causing them to appear twice. Fix #5599 (thanks @spayton)
  • When an Animation has skipMissedFrames set it will now bail out of the skip catch-up loop if any of the frames cause the animation to complete. Fix #5620 (thanks @fenrir1990 @Aveyder)
  • The Spine Plugin factory functions now use the local Scene Spine Plugin reference in order to create the objects, rather than the Scene belonging to the first instance of the plugin. This prevents errors when you have globally installed the Spine plugin, but then remove or destroy the first Scene using it (thanks stever1388 @samme)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @masterT @krotovic @Kvisaz

- JavaScript
Published by photonstorm about 5 years ago

phaser - Phaser v3.53.1

Version 3.53.1 - Anastasia - 8th March 2021

  • Fixed an issue where Container children were not removed from the display list properly.

Version 3.53.0 - Anastasia - 8th March 2021

New Features

  • You can now run Phaser from within a Web Worker. You must use the type: 'classic' method and then use importScripts('phaser.js') within your workers, but it will no longer throw window errors and allows you access to lots of the core Phaser functions from Workers.
  • Scenes.Events.PRE_RENDER is a new event fired after the display list is sorted and before the Scene is rendered (thanks @samme)
  • You can now set the boolean preserveDrawingBuffer in the Game Config (either directly, or in the Render Config). This is passed to the WebGL context during creation and controls if the buffers are automatically cleared each frame or not. The default is to clear them. Set to true to retain them.
  • GameObjects.Shape.setDisplaySize is a new method that helps setting the display width and height of a Shape object in a chainable way. Fix #5526 (thanks @samme)
  • Tilemaps.Parsers.Tiled.ParseTilesets has been updated so it now retains the type field information that can be optionally specified within Tiled. This is useful when creating objects from tiles and tile variants (thanks @lackhand)
  • Tilemaps.Parsers.Tiled.ParseWangsets is a new function that will parse the Wangset information from Tiled map data, if present, and retain it so you can access the data (thanks @lackhand)
  • WebGLPipeline.glReset is a new boolean property that keeps track of when the GL Context was last reset by the Pipeline Manager. It then redirects calls to bind to rebind instead to restore the pipeline state.

Display List Updates

  • GameObject.addToDisplayList is a new method that allows you to add a Game Object to the given Display List. If no Display List is given, it will default to the Scene Display List. A Game Object can only exist on one Display List at any given time, but may move freely between them.
  • GameObject.addToUpdateList is a new method that adds the 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.
  • GameObject.removeFromDisplayList is a new method that removes the Game Object from the Display List it is currently on.
  • GameObject.removeFromUpdateList is a new method that removes the Game Object from the Scenes Update List.
  • GameObject.destroy will now call the new removeFromDisplayList and removeFromUpdateList methods.
  • DisplayList.addChildCallback will now use the new addToDisplayList and removeFromDisplayList Game Object methods.
  • Container.addHandler will now use the new addToDisplayList and removeFromDisplayList Game Object methods.
  • Layer.addChildCallback and removeChildCallback will now use the new addToDisplayList and removeFromDisplayList Game Object methods.
  • Group now listens for the ADDED_TO_SCENE and REMOVED_FROM_SCENE methods and adds and removes itself from the Update List accordingly.
  • Group.add and create now uses the new addToDisplayList and addToUpdateList Game Object methods.
  • Group.remove now uses the new removeFromDisplayList and removeFromUpdateList Game Object methods.
  • Group.destroy has a new optional boolean parameter removeFromScene, which will remove all Group children from the Scene if specified.

Updates

  • Phaser no longer includes the IE9 polyfills. All polyfills have been removed from the core builds and moved to their own specific version called phaser-ie9, which can be found in the dist folder.
  • All of the Device functions will now check to see if Phaser is running inside of a Web Worker, or not. If it is, they will return early, avoiding trying to make calls to window or other elements not present within Workers.
  • The Webpack loaders have been moved to dev dependencies to avoid peer issues during use of Phaser as a package (thanks @andrewstart)
  • The WebAudioSoundManager.createAudioContext method is no longer private.
  • The WebAudioSoundManager.context property is no longer private.
  • The WebAudioSoundManager.masterMuteNode property is no longer private.
  • The WebAudioSoundManager.masterVolumeNode property is no longer private.
  • The WebAudioSoundManager.destination property is no longer private.
  • The WebAudioSound.audioBuffer property is no longer private.
  • The WebAudioSound.source property is no longer private.
  • The WebAudioSound.loopSource property is no longer private.
  • The WebAudioSound.muteNode property is no longer private.
  • The WebAudioSound.volumeNode property is no longer private.
  • The WebAudioSound.pannerNode property is no longer private.
  • The WebAudioSound.hasEnded property is no longer private, but is read only.
  • The WebAudioSound.hasLooped property is no longer private, but is read only.
  • The WebAudioSoundManager.createAudioContext method will now use webkitAudioContext if defined in window (rather than using the polyfill) to handle audio on Safari.
  • If a loaded JSON File fails to parse it will now issue a console warning along with the file key (thanks @samme)
  • The Canvas Renderer will no longer run a fillRect if clearBeforeRender is false in the Game Config.
  • The LightsManager.addPointlight method now has full JSDocs and the attenuation parameter.
  • LightPipeline.lightsActive is a new boolean property that keeps track if the Lights Manager in a Scene is active, or not.
  • The LightPipeline now only calls batchSprite, batchTexture and batchTextureFrame if the Scene Lights Manager is active. Fix #5522 (thanks @inmylo)
  • The Tiled Parser has been updated so it now supports object properties defined in an array with name / type values (thanks @veleek)
  • LineCurve.getTangent can now take an output vector to receive the tangent value (thanks @samme)
  • DOMElementCSSRenderer no longer sets the pointerEvents style attribute to auto. This is the default value anyway and it now means you can override it from your code by setting the pointer-events attribute directly. Fix #5470 (thanks @hayatae @endel)
  • SceneManager.loadComplete will no longer try to unlock the Sound Manager, preventing AudioContext was not allowed to start console warnings after each Scene finishes loading.
  • WebGLRenderer.deleteTexture will now run resetTextures(true) first, incase the requested texture to be deleted is currently bound. Previously, it would delete the texture and then reset them.
  • If TextureSource.destroy has a WebGL Texture it will tell the WebGL Renderer to reset the textures first, before deleting its texture.
  • Cameras.Controls.FixedKeyControl.minZoom is a new configurable property that sets the minimum camera zoom. Default to 0.001 (thanks @samme)
  • Cameras.Controls.FixedKeyControl.maxZoom is a new configurable property that sets the maximum camera zoom. Default to 1000 (thanks @samme)
  • Cameras.Controls.SmoothedKeyControl.minZoom is a new configurable property that sets the minimum camera zoom. Default to 0.001 (thanks @samme)
  • Cameras.Controls.SmoothedKeyControl.maxZoom is a new configurable property that sets the maximum camera zoom. Default to 1000 (thanks @samme)
  • The WebGLPipeline.rebind method now accepts an optional parameter currentShader. If provided it will set the current shader to be this after the pipeline reset is complete.
  • The PipelineManager.rebind method will now flag all pipelines as glReset = true, so they know to fully rebind the next time they are invoked.

Bug Fixes

  • BlitterWebGLRenderer was calling an out-dated function setRenderDepth instead of addToRenderList (thanks Harm)
  • When a loaded JSON file fails to parse, it's marked FILE_ERRORED and the Loader continues. Before this change the Loader would stall (thanks @samme)
  • Math.FromPercent silently assumed the min parameter to be 0. It can now be any value, allowing you to generate percentages between min and max correctly (thanks @somechris)
  • The Container and Zone Game Objects were not handling being added to the render list, causing them to fail input detection tests. Fix #5506 #5508 (thanks @rexrainbow @vforsh @Nightspeller)
  • IsometricWorldToTileXY was returning a tile incorrectly offset from the given coordinates. It now returns from the expected location (thanks @veleek)
  • DOMElementCSSRenderer will now return early if src.node doesn't exist or is null, rather than trying to extract the style property from it. Fix #5566 (thanks @rattias)
  • The BitmapMask will now check to see if renderer exists before trying to hook to its event emitter (thanks @mattjennings)
  • TileSprite will now check to see if renderer exists before trying to restore itself during a context loss (thanks @mattjennings)
  • A Texture will now check to see if renderer exists before resetting the WebGL textures (thanks @mattjennings)
  • Destroying a Text Game Object when using the HEADLESS renderer would cause an Uncaught TypeError. Fix #5558 (thanks @mattjennings)
  • The Actions.PlayAnimation arguments have been updated to match the new animation system introduced in Phaser 3.50. It will now take either a string-key, or a play animation configuration object, and the startFrame parameter has been replaced with ignoreIfPlaying. The function will also only call play if the Game Object has an animation component, meaning you can now supply this action with a mixed-content array without errors. Fix #5555 (thanks @xuxucode)
  • RenderTarget.resize will now Math.floor the scaled width and height as well as ensure they're not <= 0 which causes Framebuffer status: Incomplete Attachment errors. Fix #5563 #5478 (thanks @orjandh @venarius)
  • Matter.Components.Sleep.setToSleep and setAwake were documented as returning this, however they didn't return anything. Both now return this correctly. Fix #5567 (thanks @micsun-al)
  • The Particle position would be wrong when set to follow a Sprite using the Canvas Renderer. Fix #5457 (thanks @samme)
  • Fixed a conditional bug in Arcade Physics ProcessX when Body2 is Immovable and Body1 is not.
  • The Spine Plugin would throw an error while unloading and restarting the game. Fix #5477 (thanks @ayamomiji @Pong420)
  • The Spine Plugin would cause all textures to render as blue if a Spine object followed any Game Object using the Graphics Pipeline on the display list, due to the gl context restoration not being properly handled. Fix #5493 #5449 (thanks @EmilSV @FloodGames)
  • Spine Game Objects and Containers will now add themselves to the Camera render list, fixing issues where input didn't work if depth was used or they were overlapped with another interactive Game Object.
  • Calling Group.destroy would cause a runtime error if Group.runChildUpdate had been set. Fix #5576 (thanks @samme)
  • Moving a Sprite from a Container or Layer to the Scene would fail without first resetting the display list. Fix #5535 (thanks @malahaas @samme @tringcooler)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@edemaine @xuxucode @schontz @kaktus42 @Nero0 @samme

- JavaScript
Published by photonstorm about 5 years ago

phaser - Phaser v3.53.0

Version 3.53.0 - Anastasia - 8th March 2021

New Features

  • You can now run Phaser from within a Web Worker. You must use the type: 'classic' method and then use importScripts('phaser.js') within your workers, but it will no longer throw window errors and allows you access to lots of the core Phaser functions from Workers.
  • Scenes.Events.PRE_RENDER is a new event fired after the display list is sorted and before the Scene is rendered (thanks @samme)
  • You can now set the boolean preserveDrawingBuffer in the Game Config (either directly, or in the Render Config). This is passed to the WebGL context during creation and controls if the buffers are automatically cleared each frame or not. The default is to clear them. Set to true to retain them.
  • GameObjects.Shape.setDisplaySize is a new method that helps setting the display width and height of a Shape object in a chainable way. Fix #5526 (thanks @samme)
  • Tilemaps.Parsers.Tiled.ParseTilesets has been updated so it now retains the type field information that can be optionally specified within Tiled. This is useful when creating objects from tiles and tile variants (thanks @lackhand)
  • Tilemaps.Parsers.Tiled.ParseWangsets is a new function that will parse the Wangset information from Tiled map data, if present, and retain it so you can access the data (thanks @lackhand)
  • WebGLPipeline.glReset is a new boolean property that keeps track of when the GL Context was last reset by the Pipeline Manager. It then redirects calls to bind to rebind instead to restore the pipeline state.

Display List Updates

  • GameObject.addToDisplayList is a new method that allows you to add a Game Object to the given Display List. If no Display List is given, it will default to the Scene Display List. A Game Object can only exist on one Display List at any given time, but may move freely between them.
  • GameObject.addToUpdateList is a new method that adds the 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.
  • GameObject.removeFromDisplayList is a new method that removes the Game Object from the Display List it is currently on.
  • GameObject.removeFromUpdateList is a new method that removes the Game Object from the Scenes Update List.
  • GameObject.destroy will now call the new removeFromDisplayList and removeFromUpdateList methods.
  • DisplayList.addChildCallback will now use the new addToDisplayList and removeFromDisplayList Game Object methods.
  • Container.addHandler will now use the new addToDisplayList and removeFromDisplayList Game Object methods.
  • Layer.addChildCallback and removeChildCallback will now use the new addToDisplayList and removeFromDisplayList Game Object methods.
  • Group now listens for the ADDED_TO_SCENE and REMOVED_FROM_SCENE methods and adds and removes itself from the Update List accordingly.
  • Group.add and create now uses the new addToDisplayList and addToUpdateList Game Object methods.
  • Group.remove now uses the new removeFromDisplayList and removeFromUpdateList Game Object methods.
  • Group.destroy has a new optional boolean parameter removeFromScene, which will remove all Group children from the Scene if specified.

Updates

  • Phaser no longer includes the IE9 polyfills. All polyfills have been removed from the core builds and moved to their own specific version called phaser-ie9, which can be found in the dist folder.
  • All of the Device functions will now check to see if Phaser is running inside of a Web Worker, or not. If it is, they will return early, avoiding trying to make calls to window or other elements not present within Workers.
  • The Webpack loaders have been moved to dev dependencies to avoid peer issues during use of Phaser as a package (thanks @andrewstart)
  • The WebAudioSoundManager.createAudioContext method is no longer private.
  • The WebAudioSoundManager.context property is no longer private.
  • The WebAudioSoundManager.masterMuteNode property is no longer private.
  • The WebAudioSoundManager.masterVolumeNode property is no longer private.
  • The WebAudioSoundManager.destination property is no longer private.
  • The WebAudioSound.audioBuffer property is no longer private.
  • The WebAudioSound.source property is no longer private.
  • The WebAudioSound.loopSource property is no longer private.
  • The WebAudioSound.muteNode property is no longer private.
  • The WebAudioSound.volumeNode property is no longer private.
  • The WebAudioSound.pannerNode property is no longer private.
  • The WebAudioSound.hasEnded property is no longer private, but is read only.
  • The WebAudioSound.hasLooped property is no longer private, but is read only.
  • The WebAudioSoundManager.createAudioContext method will now use webkitAudioContext if defined in window (rather than using the polyfill) to handle audio on Safari.
  • If a loaded JSON File fails to parse it will now issue a console warning along with the file key (thanks @samme)
  • The Canvas Renderer will no longer run a fillRect if clearBeforeRender is false in the Game Config.
  • The LightsManager.addPointlight method now has full JSDocs and the attenuation parameter.
  • LightPipeline.lightsActive is a new boolean property that keeps track if the Lights Manager in a Scene is active, or not.
  • The LightPipeline now only calls batchSprite, batchTexture and batchTextureFrame if the Scene Lights Manager is active. Fix #5522 (thanks @inmylo)
  • The Tiled Parser has been updated so it now supports object properties defined in an array with name / type values (thanks @veleek)
  • LineCurve.getTangent can now take an output vector to receive the tangent value (thanks @samme)
  • DOMElementCSSRenderer no longer sets the pointerEvents style attribute to auto. This is the default value anyway and it now means you can override it from your code by setting the pointer-events attribute directly. Fix #5470 (thanks @hayatae @endel)
  • SceneManager.loadComplete will no longer try to unlock the Sound Manager, preventing AudioContext was not allowed to start console warnings after each Scene finishes loading.
  • WebGLRenderer.deleteTexture will now run resetTextures(true) first, incase the requested texture to be deleted is currently bound. Previously, it would delete the texture and then reset them.
  • If TextureSource.destroy has a WebGL Texture it will tell the WebGL Renderer to reset the textures first, before deleting its texture.
  • Cameras.Controls.FixedKeyControl.minZoom is a new configurable property that sets the minimum camera zoom. Default to 0.001 (thanks @samme)
  • Cameras.Controls.FixedKeyControl.maxZoom is a new configurable property that sets the maximum camera zoom. Default to 1000 (thanks @samme)
  • Cameras.Controls.SmoothedKeyControl.minZoom is a new configurable property that sets the minimum camera zoom. Default to 0.001 (thanks @samme)
  • Cameras.Controls.SmoothedKeyControl.maxZoom is a new configurable property that sets the maximum camera zoom. Default to 1000 (thanks @samme)
  • The WebGLPipeline.rebind method now accepts an optional parameter currentShader. If provided it will set the current shader to be this after the pipeline reset is complete.
  • The PipelineManager.rebind method will now flag all pipelines as glReset = true, so they know to fully rebind the next time they are invoked.

Bug Fixes

  • BlitterWebGLRenderer was calling an out-dated function setRenderDepth instead of addToRenderList (thanks Harm)
  • When a loaded JSON file fails to parse, it's marked FILE_ERRORED and the Loader continues. Before this change the Loader would stall (thanks @samme)
  • Math.FromPercent silently assumed the min parameter to be 0. It can now be any value, allowing you to generate percentages between min and max correctly (thanks @somechris)
  • The Container and Zone Game Objects were not handling being added to the render list, causing them to fail input detection tests. Fix #5506 #5508 (thanks @rexrainbow @vforsh @Nightspeller)
  • IsometricWorldToTileXY was returning a tile incorrectly offset from the given coordinates. It now returns from the expected location (thanks @veleek)
  • DOMElementCSSRenderer will now return early if src.node doesn't exist or is null, rather than trying to extract the style property from it. Fix #5566 (thanks @rattias)
  • The BitmapMask will now check to see if renderer exists before trying to hook to its event emitter (thanks @mattjennings)
  • TileSprite will now check to see if renderer exists before trying to restore itself during a context loss (thanks @mattjennings)
  • A Texture will now check to see if renderer exists before resetting the WebGL textures (thanks @mattjennings)
  • Destroying a Text Game Object when using the HEADLESS renderer would cause an Uncaught TypeError. Fix #5558 (thanks @mattjennings)
  • The Actions.PlayAnimation arguments have been updated to match the new animation system introduced in Phaser 3.50. It will now take either a string-key, or a play animation configuration object, and the startFrame parameter has been replaced with ignoreIfPlaying. The function will also only call play if the Game Object has an animation component, meaning you can now supply this action with a mixed-content array without errors. Fix #5555 (thanks @xuxucode)
  • RenderTarget.resize will now Math.floor the scaled width and height as well as ensure they're not <= 0 which causes Framebuffer status: Incomplete Attachment errors. Fix #5563 #5478 (thanks @orjandh @venarius)
  • Matter.Components.Sleep.setToSleep and setAwake were documented as returning this, however they didn't return anything. Both now return this correctly. Fix #5567 (thanks @micsun-al)
  • The Particle position would be wrong when set to follow a Sprite using the Canvas Renderer. Fix #5457 (thanks @samme)
  • Fixed a conditional bug in Arcade Physics ProcessX when Body2 is Immovable and Body1 is not.
  • The Spine Plugin would throw an error while unloading and restarting the game. Fix #5477 (thanks @ayamomiji @Pong420)
  • The Spine Plugin would cause all textures to render as blue if a Spine object followed any Game Object using the Graphics Pipeline on the display list, due to the gl context restoration not being properly handled. Fix #5493 #5449 (thanks @EmilSV @FloodGames)
  • Spine Game Objects and Containers will now add themselves to the Camera render list, fixing issues where input didn't work if depth was used or they were overlapped with another interactive Game Object.
  • Calling Group.destroy would cause a runtime error if Group.runChildUpdate had been set. Fix #5576 (thanks @samme)
  • Moving a Sprite from a Container or Layer to the Scene would fail without first resetting the display list. Fix #5535 (thanks @malahaas @samme @tringcooler)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@edemaine @xuxucode @schontz @kaktus42 @Nero0 @samme

- JavaScript
Published by photonstorm about 5 years ago

phaser - Phaser v3.52.0

Version 3.52.0 - Crusch - 14th January 2021

New Features

  • The getPostPipeline method available on most Game Objects will now return an array of piplines if an instance is given and the Game Object has more than one of those pipelines set on it. If only one pipeline is set, it will be returned directly.

Updates

  • BaseCamera.renderList is a new array that is populated with all Game Objects that the camera has rendered in the current frame. It is automatically cleared during Camera.preUpdate and is an accurate representation of the Game Objects the Camera rendered. It's used internally by the Input Plugin, but exposed should you wish to read the contents or use it for profiling.
  • BaseCamera.addToRenderList is a new method that will add the given Game Object to the Cameras current render list.
  • The InputPlugin.sortGameObjects method now uses the new Camera render list to work out the display index depths.
  • The InputPlugin.sortDropZones method is a new method, based on the old sortGameObjects method that is used for sorting input enabled drop zones.
  • The background color behind the game url in the banner is now transparent, so it looks correct with dark dev tools themes (thanks @kainage)

Bug Fixes

  • WebAudioSound.destroy now checks to see if pannerNode exists before disabling it, preventing an error in Safari (thanks @jdcook)
  • Fixed the cause of Uncaught TypeError: Cannot read property 'getIndex' of null by checking the display list property securely. Fix #5489 (thanks @actionmoon)
  • Fixed an issue where adding input-enabled Game Objects to a Layer would have the input system ignore their depth settings. Fix #5483 (thanks @pr4xx)
  • The method TilemapLayer.weightedRandomize has changed so that the parameter weightedIndexes is now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional. This change was made to the docs but not the parameters, but now works according to the docs (thanks Fantasix)
  • The Mesh GenerateVerts function was returning an object with the property verts instead of vertices as expected by the Mesh.addVertices method. It now returns the correct name (thanks @lackhand)
  • AtlasJSONFile will now call File.pendingDestroy, clearing up the resources it used during load and emitting a missing FILE_COMPLETE event. Fix #5495 (thanks @mikuso)
  • AtlasJSONFile, AtlasXMLFile, BitmapFontFile and UnityAtlasFile will now call File.pendingDestroy, clearing up the resources it used during load and emiting a missing FILE_COMPLETE event. Fix #5495 (thanks @mikuso)
  • Some Bitmap Text fonts were not rendering under Canvas due to the way in which the texture offset was calculated. It now uses the __BASE frame to get the texture offset, rather than the first frame in the set. Fix #5462 #5501 (thanks @monteiz @DPMakerQB)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@ygongdev Tucker @lackhand

- JavaScript
Published by photonstorm over 5 years ago

phaser - Phaser v3.51.0

Version 3.51.0 - Emilia - 5th January 2021

New Features

  • WebGLRenderer.isTextureClean is a new boolean property that tracks of all of the multi-textures are in a clean 'default' state, to avoid lots of gl texture binds and activations during a Scene restart or destruction process.
  • GameObject.removePostPipeline would previously only remove a single pipeline instance. Calling the method with a class will now clear all instances of the pipeline class from the Game Object (thanks @rexrainbow)

Updates

  • Layer.destroy will now call destroy on all of its children as well.
  • The Layer Game Object has been given all of the missing properties and methods from Game Object to make the class shapes identical. This includes the properties parentContainer, tabIndex, input and body. You cannot set any of these properties, they are ignored by the Layer itself. It also includes the methods: setInteractive, disableInteractive and removeInteractive. A Layer cannot be enabled for input or have a physics body. Fix #5459 (thanks @PhaserEditor2D)
  • Layer.getIndexList is a new method, taken from the Game Object, that will return the index of the Layer in the display list, factoring in any parents.

Bug Fixes

  • On some keyboards it was possible for the keyup event to not fire because it was filtered out by the Keyboard Plugin repeat key check. Fix #5472 (thanks @cjw6k)
  • Fixed issue causing Cannot read property 'pipelines' of null to be thrown if using 3.50 with the HEADLESS renderer. Fix #5468 (thanks @Grenagar)
  • Canvas Tilemap Rendering is now working again. Fix #5480 (thanks @marshmn)
  • Layer.destroy will now emit the DESTROY event at the start of the method. Fix #5466 (thanks @samme)
  • The error RENDER WARNING: there is no texture bound to the unit ... would be thrown when trying to restart a Scene. When a Scene is shutdown is will now reset the WebGL Texture cache. Fix #5464 (thanks @ffx0s)
  • The error RENDER WARNING: there is no texture bound to the unit ... would be thrown when destroying a Text Game Object, or any Game Object that uses its own custom texture. Destroying such an object will now reset the WebGL Texture cache. Fix #5464 (thanks @mark-rushakoff)
  • When using an asset pack with a prefix, and loading a Spine file, the prefix was being appended twice causing the texture to fail loading. It's now appended correctly (thanks @jdcook)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@pol0nium @ErinLMoore @umi-tyaahan @nk9

Version 3.50.1 - Subaru - 21st December 2020

  • The new Web Audio Panning feature breaks WebAudio on Safari (OSX and iOS). The stero panner node is now only created if supported. Fix #5460 (thanks @d4rkforce)

Version 3.50.0 - Subaru - 16th December 2020

Due to the massive amount of changes in 3.50 this Change Log is, by its nature, very long. It's important to scan through it, especially if you're porting a game from an earlier version of Phaser to 3.50. However, if you're after more top-level descriptions of what's new, with example code, then please see the posts we will be making to the Phaser site and Phaser Patreon in the coming months after release. We have also updated the Phaser 3 Examples site, so that every single example up there has been rewritten for 3.50, so you don't have to struggle working through old or deprecated syntax. Virtually all new features are covered in new examples, as well.

With that said, we've tried to organize the Change Log into commonly themed sections to make it more digestible, but we appreciate there is a lot here. Please don't feel overwhelmed! If you need clarification about something, join us on the Phaser Discord and feel free to ask.

WebGL Pipelines and Post Processing

WebGL Pipelines are responsible for the rendering of all Game Objects in Phaser and they have had a complete rewrite in 3.50. This was to allow for the introduction of post processing pipelines, now readily available to be created from the new Post FX Pipeline class. The changes in this area have been extensive, so if you use custom WebGL Pipelines in your game already, you must update your code to use Phaser 3.50.

Pipeline Manager

The WebGL.PipelineManager is a new class that is responsible for managing all of the WebGL Pipelines in Phaser. An instance of the Pipeline Manager is created by the WebGL Renderer and is available under the pipelines property. This means that the WebGL Renderer no longer handles pipelines directly, causing the following API changes:

  • WebGLRenderer.pipelines is no longer a plain object containing pipeline instances. It's now an instance of the PipelineManager class. This instance is created during the init and boot phase of the renderer.
  • The WebGLRenderer.currentPipeline property no longer exists, instead use PipelineManager.current.
  • The WebGLRenderer.previousPipeline property no longer exists, instead use PipelineManager.previous.
  • The WebGLRenderer.hasPipeline method no longer exists, instead use PipelineManager.has.
  • The WebGLRenderer.getPipeline method no longer exists, instead use PipelineManager.get.
  • The WebGLRenderer.removePipeline method no longer exists, instead use PipelineManager.remove.
  • The WebGLRenderer.addPipeline method no longer exists, instead use PipelineManager.add.
  • The WebGLRenderer.setPipeline method no longer exists, instead use PipelineManager.set.
  • The WebGLRenderer.rebindPipeline method no longer exists, instead use PipelineManager.rebind.
  • The WebGLRenderer.clearPipeline method no longer exists, instead use PipelineManager.clear.

The Pipeline Manager also offers the following new features:

  • The PipelineManager.resize method automatically handles resize events across all pipelines.
  • The PipelineManager.preRender method calls the pre-render method of all pipelines.
  • The PipelineManager.render method calls the render method of all pipelines.
  • The PipelineManager.postRender method calls the post-render method of all pipelines.
  • The PipelineManager.setMulti method automatically binds the Multi Texture Pipeline, Phasers default.
  • The PipelineManager.clear method will clear the pipeline, store it in previous and free the renderer.
  • The PipelineManager.rebind method will reset the rendering context and restore the previous pipeline, if set.
  • The PipelineManager.copyFrame method will copy a source Render Target to the target Render Target, optionally setting the brightness of the copy.
  • The PipelineManager.blitFrame method will copy a source Render Target to the target Render Target. Unlike copyFrame no resizing takes place and you can optionally set the brightness and erase mode of the copy.
  • The PipelineManager.copyFrameRect method binds the source Render Target and then copies a section of it to the target using gl.copyTexSubImage2D rather than a shader, making it much faster if you don't need blending or preserving alpha details.
  • The PipelineManager.copyToGame method pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws the source Render Target to it. Use when you need to render the final result to the game canvas.
  • The PipelineManager.drawFrame method will copy a source Render Target, optionally to a target Render Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy.
  • The PipelineManager.blendFrames method 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 PipelineManager.blendFramesAdditive method 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 PipelineManager.clearFrame method clears the given Render Target.

New constants have been created to help you reference a pipeline without needing to use strings:

  • Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE for the Bitmap Mask Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE for the Light 2D Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE for the Single Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE for the Multi Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE for the Rope Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINE for the Point Light Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINE for the Post FX Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINE for the Utility Pipeline.

All Game Objects have been updated to use the new constants and Pipeline Manager.

Post FX Pipeline

The Post FX Pipeline is a brand new and special kind of pipeline specifically for handling post processing effects in Phaser 3.50.

Where-as a standard Pipeline allows you to control the process of rendering Game Objects by configuring the shaders and attributes used to draw them, a Post FX Pipeline is designed to allow you to apply processing after the Game Object/s have been rendered.

Typical examples of post processing effects are bloom filters, blurs, light effects and color manipulation.

The pipeline works by creating a tiny vertex buffer with just one single hard-coded quad in it. Game Objects can have a Post Pipeline set on them, which becomes their own unique pipeline instance. Those objects are then rendered using their standard pipeline, but are redirected to the Render Targets owned by the post pipeline, which can then apply their own shaders and effects, before passing them back to the main renderer.

The following properties and methods are available in the new PostFXPipeline class:

  • The PostFXPipeline.gameObject property is a reference to the Game Object that owns the Post Pipeline, if any.
  • The PostFXPipeline.colorMatrix property is a Color Matrix instance used by the draw shader.
  • The PostFXPipeline.fullFrame1 property is a reference to the fullFrame1 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.fullFrame2 property is a reference to the fullFrame2 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.halfFrame1 property is a reference to the halfFrame1 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.halfFrame2 property is a reference to the halfFrame2 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.copyFrame method will copy a source Render Target to the target Render Target, optionally setting the brightness of the copy.
  • The PostFXPipeline.blitFrame method will copy a source Render Target to the target Render Target. Unlike copyFrame no resizing takes place and you can optionally set the brightness and erase mode of the copy.
  • The PostFXPipeline.copyFrameRect method binds the source Render Target and then copies a section of it to the target using gl.copyTexSubImage2D rather than a shader, making it much faster if you don't need blending or preserving alpha details.
  • The PostFXPipeline.copyToGame method pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws the source Render Target to it. Use when you need to render the final result to the game canvas.
  • The PostFXPipeline.drawFrame method will copy a source Render Target, optionally to a target Render Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy.
  • The PostFXPipeline.blendFrames method 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 PostFXPipeline.blendFramesAdditive method 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 PostFXPipeline.clearFrame method clears the given Render Target.
  • The PostFXPipeline.bindAndDraw method binds this pipeline and draws the source Render Target to the target Render Target. This is typically the final step taken in when post processing.

Renamed WebGL Pipelines

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

There is also the new GraphicsPipeline. Previously, the TextureTintPipeline was responsible for rendering all Sprites, Graphics, and Shape objects. Now, it only renders Sprites. All Graphics and Shapes are handled by the new GraphicsPipeline, which uses its own shaders. See below for details about this change.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

WebGL Pipelines Updates

Further pipeline changes are as follows:

  • None of the shaders or pipelines use the uViewMatrix and uModelMatrix uniforms any longer. These were always just plain identity matrices, so there is no point spending CPU and GPU time to set them as uniforms or use them in the shaders. Should you need these uniforms, you can add them to your own custom pipelines.
  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.
  • The WebGLPipeline.shouldFlush method now accepts an optional parameter amount. If given, it will return true if the amount to be added to the vertex count exceeds the vertex capacity. The Multi Pipeline has been updated to now use this method instead of performing the comparison multiple times itself.
  • The RopePipeline now extends MultiPipeline and just changes the topology, vastly reducing the file size.
  • The WebGLPipeline.flushLocked property has been removed. A pipeline can never flush in the middle of a flush anyway, so it was just wasting CPU cycles being set.
  • WebGLPipeline.manager is a new property that is a reference to the WebGL Pipeline Manager.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLPipeline.forceZero is a new boolean property that sets if the pipeline should force the use of texture zero.
  • WebGLPipeline.hasBooted is a new boolean property that is set once the pipeline has finished setting itself up and has booted.
  • WebGLPipeline.isPostFX is a new boolean property that is only set by Post FX Pipelines to help identify them.
  • WebGLPipeline.renderTargets is a new property that holds an array of WebGL Render Targets belonging to the pipeline.
  • WebGLPipeline.currentRenderTarget is a new property that holds a reference to the currently bound Render Target.
  • WebGLPipeline.shaders is a new property that holds an array of all WebGLShader instances that belong to the pipeline.
  • WebGLPipeline.currentShader is a new property that holds a reference to the currently active shader within the pipeline.
  • WebGLPipeline.config is a new property that holds the pipeline configuration object used to create it.
  • WebGLPipeline.projectionMatrix is a new property that holds a Matrix4 used as the projection matrix for the pipeline.
  • WebGLPipeline.setProjectionMatrix is a new method that allows you to set the ortho projection matrix of the pipeline.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLPipeline.setShader is a new method that allows you to set the currently active shader within the pipeline.
  • WebGLPipeline.getShaderByName is a new method that allows you to get a shader from the pipeline based on its name.
  • WebGLPipeline.setShadersFromConfig is a new method that destroys all current shaders and creates brand new ones parsed from the given config object. This is part of the pipeline boot process, but also exposed should you need to call it directly.
  • WebGLPipeline.setGameObject is a new method that custom pipelines can use in order to perform pre-batch tasks for the given Game Object.
  • WebGLPipeline.setVertexBuffer is a new method that checks if the pipelines vertex buffer is active, or not, and if not, binds it as the active buffer. This used to be performed by the WebGL Renderer, but pipelines now manage this directly.
  • WebGLPipeline.preBatch is a new method that is called when a new quad is about to be added to the batch. This is used by Post FX Pipelines to set frame buffers.
  • WebGLPipeline.postBatch is a new method that is called after a quad has been added to the batch. This is used by Post FX Pipelines to apply post processing.
  • WebGLPipeline.unbind is a new method that unbinds the current Render Target, if one is set.
  • WebGLPipeline.batchVert is a new method that adds a single vertex to the vertex buffer and increments the count by 1.
  • WebGLPipeline.batchQuad is a new method that adds a single quad (6 vertices) to the vertex buffer and increments the count, flushing first if adding the quad would exceed the batch limit.
  • WebGLPipeline.batchTri is a new method that adds a single tri (3 vertices) to the vertex buffer and increments the count, flushing first if adding the tri would exceed the batch limit.
  • WebGLPipeline.drawFillRect is a new method that pushes a filled rectangle into the vertex batch.
  • WebGLPipeline.setTexture2D is a new method that sets the texture to be bound to the next available texture unit.
  • WebGLPipeline.bindTexture is a new method that immediately activates the given WebGL Texture and binds it to the requested slot.
  • WebGLPipeline.bindRenderTarget is a new method that binds the given Render Target to a given texture slot.
  • WebGLPipeline.setTime is a new method that gets the current game loop duration to the given shader uniform.

Pipeline Hooks

The WebGLPipeline class has lots of new hooks you can use. These are all empty by default so you can safely override them in your own classes to take advantage of them:

  • WebGLPipeline.onBoot is a new hook you can override in your own pipelines that is called when the pipeline has booted.
  • WebGLPipeline.onResize is a new hook you can override in your own pipelines that is called when the pipeline is resized.
  • WebGLPipeline.onDraw is a new hook you can override in your own pipelines that is called by Post FX Pipelines every time postBatch is invoked.
  • WebGLPipeline.onActive is a new hook you can override in your own pipelines that is called every time the Pipeline Manager makes the pipeline the active pipeline.
  • WebGLPipeline.onBind is a new hook you can override in your own pipelines that is called every time a Game Object asks the Pipeline Manager to use this pipeline, even if it's already active.
  • WebGLPipeline.onRebind is a new hook you can override in your own pipelines that is called every time the Pipeline Manager needs to reset and rebind the current pipeline.
  • WebGLPipeline.onBatch is a new hook you can override in your own pipelines that is called after a new quad (or tri) has been added to the batch.
  • WebGLPipeline.onPreBatch is a new hook you can override in your own pipelines that is called before a new Game Object is about to process itself through the batch.
  • WebGLPipeline.onPostBatch is a new hook you can override in your own pipelines that is called after a new Game Object has added itself to the batch.
  • WebGLPipeline.onPreRender is a new hook you can override in your own pipelines that is called once, per frame, right before anything has been rendered.
  • WebGLPipeline.onRender is a new hook you can override in your own pipelines that is called once, per frame, by every Camera in the Scene that wants to render, at the start of the render process.
  • WebGLPipeline.onPostRender is a new hook you can override in your own pipelines that is called once, per frame, after all rendering has happened and snapshots have been taken.
  • WebGLPipeline.onBeforeFlush is a new hook you can override in your own pipelines that is called immediately before the gl.bufferData and gl.drawArrays calls are made, so you can perform any final pre-render modifications.
  • WebGLPipeline.onAfterFlush is a new hook you can override in your own pipelines that is called after gl.drawArrays, so you can perform additional post-render effects.

Pipeline Events

The WebGLPipeline class now extends the Event Emitter and emits the following new events:

  • The WebGL.Pipelines.Events.AFTER_FLUSH event is dispatched by a WebGL Pipeline right after it has issued a drawArrays command.
  • The WebGL.Pipelines.Events.BEFORE_FLUSH event is dispatched by a WebGL Pipeline right before it is about to flush.
  • The WebGL.Pipelines.Events.BIND event is dispatched by a WebGL Pipeline when it is bound by the Pipeline Manager.
  • The WebGL.Pipelines.Events.BOOT event is dispatched by a WebGL Pipeline when it has finished booting.
  • The WebGL.Pipelines.Events.DESTROY event is dispatched by a WebGL Pipeline when it begins its destruction process.
  • The WebGL.Pipelines.Events.REBIND event is dispatched by a WebGL Pipeline when the Pipeline Manager resets and rebinds it.
  • The WebGL.Pipelines.Events.RESIZE event is dispatched by a WebGL Pipeline when it is resized, usually as a result of the Renderer.

Pipeline Uniform Changes

WebGLShaders have a uniforms object that is automatically populated when the shader is created. It scans all of the active uniforms from the compiled shader and then builds an object containing their WebGLUniformLocation and a value cache.

This saves redundant gl operations for both looking-up uniform locations and setting their values if they're already the currently set values by using the local cache instead.

The WebGLPipeline classes offer a means to set uniform values on the shader (or shaders) belonging to the pipeline. Previously, calling a method such as setFloat3 on a pipeline would pass that call over to WebGLRenderer. The renderer would first check to see if the pipeline program was current, and if not, make it so, before then looking up the uniform location and finally setting it. This is a lot of steps to take for pipelines that potentially need to change uniforms for every Game Object they render.

Under the new methods, and using the new pre-cached uniform locations and values, these extra steps are skipped. The uniform value is set directly, no shader binding takes place and no location look-up happens. This dramatically reduces the number of WebGL ops being issued per frame. To clearly differentiate these pipeline methods, we have renamed them. The new method names are as follows:

  • WebGLPipeline.set1f will set a 1f uniform based on the given name.
  • WebGLPipeline.set2f will set a 2f uniform based on the given name.
  • WebGLPipeline.set3f will set a 3f uniform based on the given name.
  • WebGLPipeline.set4f will set a 4f uniform based on the given name.
  • WebGLPipeline.set1fv will set a 1fv uniform based on the given name.
  • WebGLPipeline.set2fv will set a 2fv uniform based on the given name.
  • WebGLPipeline.set3fv will set a 3fv uniform based on the given name.
  • WebGLPipeline.set4fv will set a 4fv uniform based on the given name.
  • WebGLPipeline.set1iv will set a 1iv uniform based on the given name.
  • WebGLPipeline.set2iv will set a 2iv uniform based on the given name.
  • WebGLPipeline.set3iv will set a 3iv uniform based on the given name.
  • WebGLPipeline.set4iv will set a 4iv uniform based on the given name.
  • WebGLPipeline.set1i will set a 1i uniform based on the given name.
  • WebGLPipeline.set2i will set a 2i uniform based on the given name.
  • WebGLPipeline.set3i will set a 3i uniform based on the given name.
  • WebGLPipeline.set4i will set a 4i uniform based on the given name.
  • WebGLPipeline.setMatrix2fv will set a matrix 2fv uniform based on the given name.
  • WebGLPipeline.setMatrix3fv will set a matrix 3fv uniform based on the given name.
  • WebGLPipeline.setMatrix4fv will set a matrix 4fv uniform based on the given name.

If your code uses any of the old method names, please update them using the list below:

  • WebGLPipeline.setFloat1 has been removed. Please use set1f instead.
  • WebGLPipeline.setFloat2 has been removed. Please use set2f instead.
  • WebGLPipeline.setFloat3 has been removed. Please use set3f instead.
  • WebGLPipeline.setFloat4 has been removed. Please use set4f instead.
  • WebGLPipeline.setFloat1v has been removed. Please use set1fv instead.
  • WebGLPipeline.setFloat2v has been removed. Please use set2fv instead.
  • WebGLPipeline.setFloat3v has been removed. Please use set3fv instead.
  • WebGLPipeline.setFloat4v has been removed. Please use set4fv instead.
  • WebGLPipeline.setInt1 has been removed. Please use set1i instead.
  • WebGLPipeline.setInt2 has been removed. Please use set2i instead.
  • WebGLPipeline.setInt3 has been removed. Please use set3i instead.
  • WebGLPipeline.setInt4 has been removed. Please use set4i instead.
  • WebGLPipeline.setMatrix1 has been removed. Please use setMatrix2fv instead.
  • WebGLPipeline.setMatrix2 has been removed. Please use setMatrix3fv instead.
  • WebGLPipeline.setMatrix3 has been removed. Please use setMatrix4fv instead.

Game Object Pipeline Component Updates

To support the new Post Pipelines in 3.50, the Pipeline Component which most Game Objects inherit has been updated. That means the following new properties and methods are available on all Game Objects that have this component, such as Sprite, Layer, Rope, etc.

  • hasPostPipeline is a new boolean property that indicates if the Game Object has one, or more post pipelines set.
  • postPipelines is a new property that contains an array of Post Pipelines owned by the Game Object.
  • pipelineData is a new object object to store pipeline specific data in.
  • The setPipeline method has been updated with 2 new parameters: pipelineData and copyData. These allow you to populate the pipeline data object during setting.
  • You can now pass a pipeline instance to the setPipeline method, as well as a string.
  • setPostPipeline is a new method that allows you to set one, or more, Post FX Pipelines on the Game Object. And optionally set the pipeline data with them.
  • setPipelineData is a new method that allows you to set a key/value pair into the pipeline data object in a chainable way.
  • getPostPipeline is a new method that will return a Post Pipeline instance from the Game Object based on the given string, function or instance.
  • The resetPipeline method has two new parameters resetPostPipeline and resetData, both false by default, that will reset the Post Pipelines and pipeline data accordingly.
  • resetPostPipeline is a new method that will specifically reset just the Post Pipelines, and optionally the pipeline data.
  • removePostPipeline is a new method that will destroy and remove the given Post Pipeline from the Game Object.

Utility Pipeline

The Utility Pipeline is a brand new default special-use WebGL Pipeline that is created by and belongs to the Pipeline Manager.

It provides 4 shaders and handy associated methods:

1) Copy Shader. A fast texture to texture copy shader with optional brightness setting. 2) Additive Blend Mode Shader. Blends two textures using an additive blend mode. 3) Linear Blend Mode Shader. Blends two textures using a linear blend mode. 4) Color Matrix Copy Shader. Draws a texture to a target using a Color Matrix.

You do not extend this pipeline, but instead get a reference to it from the Pipeline Manager via the setUtility method. You can also access its methods, such as copyFrame, directly from both the Pipeline Manager and from Post FX Pipelines, where its features are most useful.

This pipeline provides methods for manipulating framebuffer backed textures, such as copying or blending one texture to another, copying a portion of a texture, additively blending two textures, flipping textures and more. All essential and common operations for post processing.

The following properties and methods are available in the new UtilityPipeline class:

  • The UtilityPipeline.colorMatrix property is an instance of a ColorMatrix class, used by the draw shader.
  • The UtilityPipeline.copyShader property is a reference to the Copy Shader.
  • The UtilityPipeline.addShader property is a reference to the additive blend shader.
  • The UtilityPipeline.linearShader property is a reference to the linear blend shader.
  • The UtilityPipeline.colorMatrixShader property is a reference to the color matrix (draw) shader.
  • The UtilityPipeline.fullFrame1 property is a full sized Render Target that can be used as a temporary buffer during post processing calls.
  • The UtilityPipeline.fullFrame2 property is a full sized Render Target that can be used as a temporary buffer during post processing calls.
  • The UtilityPipeline.halfFrame1 property is a half sized Render Target that can be used as a temporary buffer during post processing calls, where a small texture is required for more intensive operations.
  • The UtilityPipeline.halfFrame2 property is a half sized Render Target that can be used as a temporary buffer during post processing calls, where a small texture is required for more intensive operations.
  • The UtilityPipeline.copyFrame method will copy a source Render Target to the target Render Target, optionally setting the brightness of the copy.
  • The UtilityPipeline.blitFrame method will copy a source Render Target to the target Render Target. Unlike copyFrame no resizing takes place and you can optionally set the brightness and erase mode of the copy.
  • The UtilityPipeline.copyFrameRect method binds the source Render Target and then copies a section of it to the target using gl.copyTexSubImage2D rather than a shader, making it much faster if you don't need blending or preserving alpha details.
  • The UtilityPipeline.copyToGame method pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws the source Render Target to it. Use when you need to render the final result to the game canvas.
  • The UtilityPipeline.drawFrame method will copy a source Render Target, optionally to a target Render Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy.
  • The UtilityPipeline.blendFrames method 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 UtilityPipeline.blendFramesAdditive method 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 UtilityPipeline.clearFrame method clears the given Render Target.
  • The UtilityPipeline.setUVs method allows you to set the UV values for the 6 vertices that make-up the quad belonging to the Utility Pipeline.
  • The UtilityPipeline.setTargetUVs method sets the vertex UV coordinates of the quad used by the shaders so that they correctly adjust the texture coordinates for a blit frame effect.
  • The UtilityPipeline.flipX method horizontally flips the UV coordinates of the quad used by the shaders.
  • The UtilityPipeline.flipY method vertically flips the UV coordinates of the quad used by the shaders.
  • The UtilityPipeline.resetUVs method resets the quad vertice UV values to their default settings.

Light Pipeline Update

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh Game Objects now support rendering with normal maps.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Point Lights Pipeline

The Point Light Pipeline is a brand new pipeline in 3.50 that was creates specifically for rendering the new Point Light Game Objects in WebGL.

It extends the WebGLPipeline and sets the required shader attributes and uniforms for Point Light rendering.

You typically don't access or set the pipeline directly, but rather create instances of the Point Light Game Object instead. However, it does have the following unique methods:

  • The PointLightPipeline.batchPointLight method is a special-case method that is called directly by the Point Light Game Object during rendering and allows it to add itself into the rendering batch.
  • The PointLightPipeline.batchLightVert method is a special internal method, used by batchPointLight that adds a single Point Light vert into the batch.

Graphics Pipeline and Graphics Game Object Changes

The Graphics Pipeline is a new pipeline added in 3.50 that is responsible for rendering Graphics Game Objects and all of the Shape Game Objects, such as Arc, Rectangle, Star, etc. Due to the new pipeline some changes have been made:

  • The Graphics Pipeline now uses much simpler vertex and fragment shaders with just two attributes (inPosition and inColor), making the vertex size and memory-use 57% smaller.
  • The private _tempMatrix1, 2, 3 and 4 properties have all been removed from the pipeline.
  • A new public calcMatrix property has been added, which Shape Game Objects use to maintain transform state during rendering.
  • The Graphics Pipeline no longer makes use of tintEffect or any textures.
  • Because Graphics and Shapes now render with their own pipeline, you are able to exclude the pipeline and those Game Objects entirely from custom builds, further reducing the final bundle size.

As a result of these changes the following features are no longer available:

  • Graphics.setTexture has been removed. You can no longer use a texture as a 'fill' for a Graphic. It never worked with any shape other than a Rectangle, anyway, due to UV mapping issues, so is much better handled via the new Mesh Game Object.
  • Graphics._tempMatrix1, 2 and 3 have been removed. They're not required internally any longer.
  • Graphics.renderWebGL now uses the standard GetCalcMatrix function, cutting down on duplicate code significantly.

Single Pipeline Update

There is a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGLShader

WebGLShader is a new class that is created and belongs to WebGL Pipeline classes. When the pipeline is created it will create a WebGLShader instance for each one of its shaders, as defined in the pipeline configuration.

This class encapsulates everything needed to manage a shader in a pipeline, including the shader attributes and uniforms, as well as lots of handy methods such as set2f, for setting uniform values on this shader. Uniform values are automatically cached to avoid unnecessary gl operations.

Typically, you do not create an instance of this class directly, as it works in unison with the pipeline to which it belongs. You can gain access to this class via a pipeline's shaders array, post-creation.

The following properties and methods are available in the new WebGLShader class:

  • The WebGLShader.pipeline property is a reference to the WebGL Pipeline that owns the WebGLShader instance.
  • The WebGLShader.name property is the name of the shader.
  • The WebGLShader.renderer property is a reference to the WebGL Renderer.
  • The WebGLShader.gl property is a reference to the WebGL Rendering Context.
  • The WebGLShader.program property is the WebGL Program created from the vertex and fragment shaders.
  • The WebGLShader.attributes property is an array of objects that describe the vertex attributes of the shader.
  • The WebGLShader.vertexComponentCount property is the total amount of vertex attribute components of 32-bit length.
  • The WebGLShader.vertexSize property is the size, in bytes, of a single vertex.
  • The WebGLShader.uniforms property is an object that is automatically populated with all active uniforms in the shader.
  • The WebGLShader.createAttributes method takes the vertex attributes config and parses it, creating the shader attributes. This is called automatically.
  • The WebGLShader.bind method sets the program the shader uses as being active. Called automatically when the parent pipeline needs this shader.
  • The WebGLShader.rebind method sets the program the shader uses as being active and resets all of the vertex attribute pointers.
  • The WebGLShader.setAttribPointers method sets the vertex attribute pointers. Called automatically during bind.
  • The WebGLShader.createUniforms method populates the uniforms object with details about all active uniforms.
  • The WebGLShader.hasUniform method returns a boolean if the given uniform exists.
  • The WebGLShader.resetUniform method resets the cached value for the given uniform.
  • The WebGLShader.setUniform1 method is an internal method used for setting a single value uniform on the shader.
  • The WebGLShader.setUniform2 method is an internal method used for setting a double value uniform on the shader.
  • The WebGLShader.setUniform3 method is an internal method used for setting a triple value uniform on the shader.
  • The WebGLShader.setUniform4 method is an internal method used for setting a quadruple value uniform on the shader.
  • The WebGLShader.set1f method sets a 1f uniform based on the given name.
  • The WebGLShader.set2f method sets a 2f uniform based on the given name.
  • The WebGLShader.set3f method sets a 3f uniform based on the given name.
  • The WebGLShader.set4f method sets a 4f uniform based on the given name.
  • The WebGLShader.set1fv method sets a 1fv uniform based on the given name.
  • The WebGLShader.set2fv method sets a 2fv uniform based on the given name.
  • The WebGLShader.set3fv method sets a 3fv uniform based on the given name.
  • The WebGLShader.set4fv method sets a 4fv uniform based on the given name.
  • The WebGLShader.set1iv method sets a 1iv uniform based on the given name.
  • The WebGLShader.set2iv method sets a 2iv uniform based on the given name.
  • The WebGLShader.set3iv method sets a 3iv uniform based on the given name.
  • The WebGLShader.set4iv method sets a 4iv uniform based on the given name.
  • The WebGLShader.set1i method sets a 1i uniform based on the given name.
  • The WebGLShader.set2i method sets a 2i uniform based on the given name.
  • The WebGLShader.set3i method sets a 3i uniform based on the given name.
  • The WebGLShader.set4i method sets a 4i uniform based on the given name.
  • The WebGLShader.setMatrix2fv method sets a matrix 2fv uniform based on the given name.
  • The WebGLShader.setMatrix3fv method sets a matrix 3fv uniform based on the given name.
  • The WebGLShader.setMatrix4fv method sets a matrix 4fv uniform based on the given name.
  • The WebGLShader.destroy method removes all external references and deletes the program and attributes.

Render Target

RenderTarget is a brand new class that encapsulates a WebGL framebuffer and the WebGL Texture that displays it. Instances of this class are typically created by, and belong to WebGL Pipelines, however other Game Objects and classes can take advantage of Render Targets as well.

The following properties and methods are available in the new RenderTexture class:

  • The RenderTarget.renderer property is a reference to the WebGL Renderer.
  • The RenderTarget.framebuffer property is the WebGLFramebuffer belonging to the Render Target.
  • The RenderTarget.texture property is a WebGLTexture belonging to the Render Target and bound to the framebuffer.
  • The RenderTarget.width property is the width of the Render Target.
  • The RenderTarget.height property is the height of the Render Target.
  • The RenderTarget.scale property is the scale of the Render Target, applied to the dimensions during resize.
  • The RenderTarget.minFilter property is the min filter of the texture.
  • The RenderTarget.autoClear property is a boolean that controls if the Render Target is automatically cleared when bound.
  • The RenderTarget.autoResize property is a boolean that controls if the Render Target is automatically resized if the WebGLRenderer resizes.
  • The RenderTarget.setAutoResize method lets you set the auto resize of the Render Target.
  • The RenderTarget.resize method lets you resize the Render Target.
  • The RenderTarget.bind method sets the Render Target as being the active fbo in the renderer and optionally clears and adjusts the viewport.
  • The RenderTarget.adjustViewport method sets the viewport to match the Render Target dimensions.
  • The RenderTarget.clear method disables the scissors, clears the Render Target and resets the scissors again.
  • The RenderTarget.unbind method flushes the renderer and pops the Render Target framebuffer from the stack.
  • The RenderTarget.destroy method removes all external references and deletes the framebuffer and texture.

WebGL Renderer

New WebGL Multi-Texture Support

The Multi Pipeline (previously called the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw-call bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.
  • The WebGL.Utils.getComponentCount function has been removed as this is no longer required internally.

WebGLRenderer New Features, Updates and API Changes

  • WebGLRenderer.instancedArraysExtension is a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.
  • WebGLRenderer.vaoExtension is a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.
  • WebGLRenderer.resetProgram is a new method that will rebind the current program, without flushing or changing any properties.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • WebGLRenderer.finalType is a new boolean property that signifies if the current Game Object being rendered is the final one in the list.
  • The WebGLRenderer.updateCanvasTexture method will now set gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL to true, which should stop issues where you update a Text Game Object, having added a Render Texture or Spine Game Object to the Scene after it, which switches the PMA setting. Fix #5064 #5155 (thanks @hugoruscitti @immangrove-supertree)
  • WebGLRenderer.previousPipeline is a new property that is set during a call to clearPipeline and used during calls to rebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.
  • The WebGLRenderer.rebindPipeline method has been changed slightly. Previously, you had to specify the pipelineInstance, but this is now optional. If you don't, it will use the new previousPipeline property instead. If not set, or none given, it will now return without throwing gl errors as well.
  • WebGLRenderer.defaultScissor is a new property that holds the default scissor dimensions for the renderer. This is modified during resize and avoids continuous array generation in the preRender loop.
  • The WebGLRenderer.nativeTextures array has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in the TextureSource objects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy.
  • The WebGLRenderer.deleteTexture method has a new optional boolean parameter reset which allows you to control if the WebGLRenderer.resetTextures method is called, or not, after the texture is deleted.
  • The WebGLRenderer.getMaxTextures method has been removed. This is no longer needed as you can use the WebGLRenderer.maxTextures property instead.
  • The WebGLRenderer.setProgram method now returns a boolean. true if the program was set, otherwise false.
  • WebGLRenderer.setFloat1 has been removed. Use WebGLPipeline.set1f or WebGLShader.set1f instead.
  • WebGLRenderer.setFloat2 has been removed. Use WebGLPipeline.set2f or WebGLShader.set2f instead.
  • WebGLRenderer.setFloat3 has been removed. Use WebGLPipeline.set3f or WebGLShader.set3f instead.
  • WebGLRenderer.setFloat4 has been removed. Use WebGLPipeline.set4f or WebGLShader.set4f instead.
  • WebGLRenderer.setFloat1v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set1fv instead.
  • WebGLRenderer.setFloat2v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set2fv instead.
  • WebGLRenderer.setFloat3v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set3fv instead.
  • WebGLRenderer.setFloat4v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set4fv instead.
  • WebGLRenderer.setInt1 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set1i instead.
  • WebGLRenderer.setInt2 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set2i instead.
  • WebGLRenderer.setInt3 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set3i instead.
  • WebGLRenderer.setInt4 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set4i instead.
  • WebGLRenderer.setMatrix2 has been removed. Use WebGLPipeline.setMatrix2fv or WebGLShader.setMatrix2fv instead.
  • WebGLRenderer.setMatrix3 has been removed. Use WebGLPipeline.setMatrix3fv or WebGLShader.setMatrix3fv instead.
  • WebGLRenderer.setMatrix4 has been removed. Use WebGLPipeline.setMatrix4fv or WebGLShader.setMatrix4fv instead.
  • The WebGLRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.
  • WebGLRenderer.fboStack is a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.
  • WebGLRenderer.pushFramebuffer is a new method that is used to push a framebuffer onto the fbo stack before setting it as the current framebuffer. This should now be called in place of setFramebuffer. Remember to call popFramebuffer after using it.
  • WebGLRenderer.popFramebuffer is a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.
  • WebGLRenderer.setFramebuffer has a new optional boolean parameter resetTextures which will reset the WebGL Textures, if set to true (which is the default).
  • WebGLRenderer.isBooted is a new boolean property that lets you know if the renderer has fully finished booting.
  • The WebGLRenderer now extends the Event Emitter, allowing you to listen to renderer specific events.
  • WebGLRenderer.defaultCamera has been removed as it's not used anywhere internally any longer.
  • The WebGLRenderer.setVertexBuffer method has been removed along with the WebGLRenderer.currentVertexBuffer property. This is now set directly by the WebGL Pipeline, as needed.
  • The WebGLRenderer.setIndexBuffer method has been removed along with the WebGLRenderer.currentIndexBuffer property. This is now set directly by the WebGL Pipeline, as needed.
  • WebGLRenderer.resetScissor is a new method that will reset the gl scissor state to be the current scissor, if there is one, without modifying the stack.
  • WebGLRenderer.resetViewport is a new method that will reset the gl viewport to the current renderer dimensions.
  • WebGLRenderer.renderTarget is a new property that contains a Render Target that is bound to the renderer and kept resized to match it.
  • WebGLRenderer.beginCapture is a new method that will bind the renderers Render Target, so everything drawn is redirected to it.
  • WebGLRenderer.endCapture is a new method that will unbind the renderers Render Target and return it, preventing anything else from being drawn to it.
  • WebGLRenderer.setProjectionMatrix is a new method that sets the global renderer projection matrix to the given dimensions.
  • WebGLRenderer.resetProjectionMatrix is a new method that resets the renderer projection matrix back to match the renderer size.
  • WebGLRenderer.getAspectRatio is a new method that returns the aspect ratio of the renderer.

WebGL ModelViewProjection Removed

The ModelViewProjection object contained a lot of functions that Phaser never used internally. Instead, the functions available in them were already available in the Math.Matrix4 class. So the pipelines have been updated to use a Matrix4 instead and all of the MVP functions have been removed. The full list of removed functions is below:

  • projIdentity has been removed.
  • projPersp has been removed.
  • modelRotateX has been removed.
  • modelRotateY has been removed.
  • modelRotateZ has been removed.
  • viewLoad has been removed.
  • viewRotateX has been removed.
  • viewRotateY has been removed.
  • viewRotateZ has been removed.
  • viewScale has been removed.
  • viewTranslate has been removed.
  • modelIdentity has been removed.
  • modelScale has been removed.
  • modelTranslate has been removed.
  • viewIdentity has been removed.
  • viewLoad2D has been removed.
  • projOrtho has been removed.

WebGL and Canvas Renderer Events

  • Phaser.Renderer.Events is a new namespace for events emitted by the Canvas and WebGL Renderers.
  • Renderer.Events.PRE_RENDER is a new event dispatched by the Phaser Renderer. This happens right at the start of the render process.
  • Renderer.Events.RENDER is a new event dispatched by the Phaser Renderer. This happens once for every camera, in every Scene at the start of its render process.
  • Renderer.Events.POST_RENDER is a new event dispatched by the Phaser Renderer. This happens right at the end of the render process.
  • Renderer.Events.RESIZE is a new event dispatched by the Phaser Renderer whenever it is resized.

Canvas Renderer Updates

  • CanvasRenderer.isBooted is a new boolean property that lets you know if the renderer has fully finished booting.
  • The CanvasRenderer now extends the Event Emitter, allowing you to listen to renderer specific events.

Camera - New Features, Updates and API Changes

The Camera API has changed in line with the new pipeline updates. To this end, the following changes have taken place:

The Camera class now inherits the Pipeline Component. This gives it new features, in line with the other pipelines changes in 3.50, such as Camera.setPipeline, Camera.setPostPipeline, Camera.setPipelineData and so on. This is a much more powerful and flexible way of setting camera effects, rather than it managing its own framebuffer and texture directly.

To that end, the following properties and methods have been removed to tidy things up:

  • The Camera.renderToTexture property has been removed. Effects are now handled via pipelines.
  • The Camera.renderToGame property has been removed. Effects are now handled via pipelines.
  • The Camera.canvas property has been removed. Textures are handled by pipelines.
  • The Camera.context property has been removed. Textures are handled by pipelines.
  • The Camera.glTexture property has been removed. GL Textures are handled by pipelines.
  • The Camera.framebuffer property has been removed. GL Framebuffers are handled by pipelines.
  • The Camera.setRenderToTexture method has been removed. Effects are now handled via pipelines.
  • The Camera.clearRenderToTexture method has been removed. Effects are now handled via pipelines.

These changes mean that you can no longer render a Camera to a canvas in Canvas games.

Other changes and fixes:

  • Camera.zoomX is a new property that allows you to specifically set the horizontal zoom factor of a Camera.
  • Camera.zoomY is a new property that allows you to specifically set the vertical zoom factor of a Camera.
  • The Camera.setZoom method now allows you to pass two parameters: x and y, to control the zoomX and zoomY values accordingly.
  • The Camera.zoom property now returns an average of the zoomX and zoomY properties.
  • Cameras.Scene2D.Events.FOLLOW_UPDATE is a new Event that is dispatched by a Camera when it is following a Game Object. It is dispatched every frame, right after the final Camera position and internal matrices have been updated. Use it if you need to react to a camera, using its most current position and the camera is following something. Fix #5253 (thanks @rexrainbow)
  • If the Camera has roundPixels set it will now round the internal scroll factors and worldView during the preRender step. Fix #4464 (thanks @Antriel)

Spine Plugin - New Features, API Changes and Bug Fixes

  • The Spine Runtimes have been updated to 3.8.99, which are the most recent non-beta versions. Please note, you will need to re-export your animations if you're working in a version of Spine lower than 3.8.20. We do not impose this requirement, the Spine editor does.
  • SpineContainer is a new Game Object available via this.add.spineContainer to which you can add Spine Game Objects only. It uses a special rendering function to retain batching, even across multiple container or Spine Game Object instances, resulting in dramatically improved performance compared to using regular Containers. You can still use regular Containers if you need, but they do not benefit from the new batching.
  • A Spine Game Object with setVisible(false) will no longer still cause internal gl commands and is now properly skipped, retaining any current batch in the process. Fix #5174 (thanks @Kitsee)
  • The Spine Game Object WebGL Renderer will no longer clear the type if invisible and will only end the batch if the next type doesn't match.
  • The Spine Game Object WebGL Renderer will no longer rebind the pipeline if it was the final object on the display list, saving lots of gl commands.
  • The Webpack build scripts have all been updated for Webpack 4.44.x. Fix #5243 (thanks @RollinSafary)
  • There is a new npm script npm run plugin.spine.runtimes which will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo into plugins/spine/ in order for this to work and then run npm i.
  • Spine Game Objects can now be rendered to Render Textures. Fix #5184 (thanks @Kitsee)
  • Using > 128 Spine objects in a Container would cause a WebGL: INVALID_OPERATION: vertexAttribPointer: no ARRAY_BUFFER is bound and offset is non-zero error if you added any subsequent Spine objects to the Scene. There is now no limit. Fix #5246 (thanks @d7561985)
  • The Spine Plugin will now work in HEADLESS mode without crashing. Fix #4988 (thanks @raimon-segura)
  • Spine Game Objects now use -1 as their default blend mode, which means 'skip setting it', as blend modes should be handled by the Spine skeletons directly.
  • The Spine TypeScript defs have been updated for the latest version of the plugin and to add SpineContainers.
  • The SpineGameObject.setAnimation method will now use the trackIndex parameter if ignoreIfPlaying is set and run the check against this track index. Fix #4842 (thanks @vinerz)
  • The SpineFile will no longer throw a warning if adding a texture into the Texture Manager that already exists. This allows you to have multiple Spine JSON use the same texture file, however, it also means you now get no warning if you accidentally load a texture that exists, so be careful with your keys! Fix #4947 (thanks @Nomy1)
  • The Spine Plugin destroy method will now no longer remove the Game Objects from the Game Object Factory, or dispose of the Scene Renderer. This means when a Scene is destroyed, it will keep the Game Objects in the factory for other Scenes to use. Fix #5279 (thanks @Racoonacoon)
  • SpinePlugin.gameDestroy is a new method that is called if the Game instance emits a destroy event. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.
  • SpineFile will now check to see if another identical atlas in the load queue is already loading the texture it needs and will no longer get locked waiting for a file that will never complete. This allows multiple skeleton JSONs to use the same atlas data. Fix #5331 (thanks @Racoonacoon)
  • SpineFile now uses a ! character to split the keys, instead of an underscore, preventing the plugin from incorrectly working out the keys for filenames with underscores in them. Fix #5336 (thanks @Racoonacoon)
  • SpineGameObject.willRender is no longer hard-coded to return true. It instead now takes a Camera parameter and performs all of the checks needed before returning. Previously, this happened during the render functions.
  • The Spine Plugin now uses a single instance of the Scene Renderer when running under WebGL. All instances of the plugin (installed per Scene) share the same base Scene Renderer, avoiding duplicate allocations and resizing events under multi-Scene games. Fix #5286 (thanks @spayton BunBunBun)

Game Objects - New Features, API Changes and Bug Fixes

Lots of the core Phaser Game Objects have been improved in 3.50 and there are several new Game Objects as well.

Render Texture Game Object

The Render Texture Game Object has been rewritten to use the new RenderTarget class internally, rather than managing its own framebuffer and gl textures directly. The core draw methods are now a lot simpler and no longer require manipulating render pipelines.

As a result of these changes the following updates have happened:

  • RenderTexture.renderTarget is a new property that contains a RenderTarget instance, which is used for all drawing.
  • The RenderTexture.framebuffer property has been removed. You can now access this via RenderTexture.renderTarget.framebuffer.
  • The RenderTexture.glTexture property has been removed. You can now access this via RenderTexture.renderTarget.texture.
  • The RenderTexture.gl property has been removed.

Render Textures have the following new features:

  • RenderTexture.beginDraw is a new method that allows you to create a batched draw to the Render Texture. Use this method to begin the batch.
  • RenderTexture.batchDraw is a new method that allows you to batch the drawing of an object to the Render Texture. You should never call this method unless you have previously started a batch with beginDraw. You can call this method as many times as you like, to draw as many objects as you like, without causing a framebuffer bind.
  • RenderTexture.batchDrawFrame is a new method that allows you to batch the drawing of a texture frame to the Render Texture. You should never call this method unless you have previously started a batch with beginDraw. You can call this method as many times as you like, to draw as many frames as you like, without causing a framebuffer bind.
  • RenderTexture.endDraw is a new method that ends a previously created batched draw on the Render Texture. Use it to write all of your batch changes to the Render Texture.
  • You can now draw a Group to a RenderTexture. Previously, it failed to pass the camera across, resulting in none of the Group children being drawn. Fix #5330 (thanks @somnolik)

Render Textures have the following bug fixes:

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • RenderTexture.erase has never worked when using the Canvas Renderer and a texture frame, only with Game Objects. It now works with both. Fix #5422 (thanks @vforsh)

Point Lights Game Object

The Point Light Game Object is brand new in 3.50 and 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 radial 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 calculations. 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 display 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 PointLight Game Object has the following unique properties and methods:

  • The PointLight.color property is an instance of the Color object that controls the color value of the light.
  • The PointLight.intensity property sets the intensity of the light. The colors of the light are multiplied by this value during rendering.
  • The PointLight.attenuation property sets the attenuation of the light, which is the force with which the light falls off from its center.
  • The PointLight.radius property sets the radius of the light, in pixels. This value is also used for culling.

Point Lights also have corresponding Factory and Creator functions, available from within a Scene:

js this.add.pointlight(x, y, color, radius, intensity, attenuation);

and

js this.make.pointlight({ x, y, color, radius, intensity, attenuation });

Mesh Game Object

The Mesh Game Object has been rewritten from scratch in v3.50 with a lot of changes to make it much more useful. It is accompanied by the new Geom.Mesh set of functions.

  • Geom.Mesh is a new namespace that contains the Mesh related geometry functions. These are stand-alone functions that you may, or may not require, depending on your game.
  • Geom.Mesh.Vertex is a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.
  • Geom.Mesh.Face is a new class that consists of references to the three Vertex instances that construct a single Face in a Mesh and provides methods for manipulating them.
  • Geom.Mesh.GenerateVerts is a new function that will return an array of Vertex and Face objects generated from the given data. You can provide index, or non-index vertex lists, along with UV data, normals, colors and alpha which it will parse and return the results from.
  • Geom.Mesh.GenerateGridVerts is a new function that will generate a series of Vertex objects in a grid format, based on the given GenerateGridConfig config file. You can set the size of the grid, the number of segments to split it into, translate it, color it and tile the texture across it. The resulting data can be easily used by a Mesh Game Object.
  • Geom.Mesh.GenerateObjVerts is a new function that will generate a series of Vertex objects based on the given parsed Wavefront Obj Model data. You can optionally scale and translate the generated vertices and add them to a Mesh.
  • Geom.Mesh.ParseObj is a new function that will parse a triangulated Wavefront OBJ file into model data into a format that the GenerateObjVerts function can consume.
  • Geom.Mesh.ParseObjMaterial is a new function that will parse a Wavefront material file and extract the diffuse color data from it, combining it with the parsed object data.
  • Geom.Mesh.RotateFace is a new function that will rotate a Face by a given amount, based on an optional center of rotation.
  • Loader.OBJFile is a new File Loader type that can load triangulated Wavefront OBJ files, and optionally material files, which are then parsed and stored in the OBJ Cache.
  • The Mesh constructor and MeshFactory signatures have changed to scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first. indicies is a new parameter that allows you to provide indexed vertex data to create the Mesh from, where the indicies array holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. The indicies array is optional. If your data is not indexed, then simply pass null or an empty array for this parameter.
  • The Mesh Game Object now has the Animation State Component. This allows you to create and play animations across the texture of a Mesh, something that previously wasn't possible. As a result, the Mesh now adds itself to the Update List when added to a Scene.
  • Mesh.addVertices is a new method that allows you to add vertices to a Mesh Game Object based on the given parameters. This allows you to modify a mesh post-creation, or populate it with data at a later stage.
  • Mesh.addVerticesFromObj is a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the new OBJFile with a this.load.obj call, then you can use the key with this method. This method also takes an optional scale and position parameters to control placement of the created model within the Mesh.
  • Mesh.hideCCW is a new boolean property that, when enabled, tells a Face to not render if it isn't counter-clockwise. You can use this to hide backward facing Faces.
  • Mesh.modelPosition is a new Vector3 property that allows you to translate the position of all vertices in the Mesh.
  • Mesh.modelRotation is a new Vector3 property that allows you to rotate all vertices in the Mesh.
  • Mesh.modelScale is a new Vector3 property that allows you to scale all vertices in the Mesh.
  • Mesh.panX is a new function that will translate the view position of the Mesh on the x axis.
  • Mesh.panY is a new function that will translate the view position of the Mesh on the y axis.
  • Mesh.panZ is a new function that will translate the view position of the Mesh on the z axis.
  • Mesh.setPerspective is a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.
  • Mesh.setOrtho is a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.
  • Mesh.clear is a new method that will destroy all Faces and Vertices and clear the Mesh.
  • Mesh.depthSort is a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.
  • Mesh.addVertex is a new method that allows you to add a new single Vertex into the Mesh.
  • Mesh.addFace is a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.
  • Mesh.getFaceCount new is a new method that will return the total number of Faces in the Mesh.
  • Mesh.getVertexCount new is a new method that will return the total number of Vertices in the Mesh.
  • Mesh.getFace new is a new method that will return a Face instance from the Mesh based on the given index.
  • Mesh.getFaceAt new is a new method that will return an array of Face instances from the Mesh based on the given position. The position is checked against each Face, translated through the optional Camera and Mesh matrix. If more than one Face intersects, they will all be returned but the array will be depth sorted first, so the first element will be that closest to the camera.
  • Mesh.vertices is now an array of GameObject.Vertex instances, not a Float32Array.
  • Mesh.faces is a new array of GameObject.Face instances, which is populated during a call to methods like addVertices or addModel.
  • Mesh.totalRendered is a new property that holds the total number of Faces that were rendered in the previous frame.
  • Mesh.setDebug is a new method that allows you to render a debug visualization of the Mesh vertices to a Graphics Game Object. You can provide your own Graphics instance and optionally callback that is invoked during rendering. This allows you to easily visualize the vertices of your Mesh to help debug UV mapping.
  • The Mesh now renders by iterating through the Faces array, not the vertices. This allows you to use Array methods such as BringToTop to reposition a Face, thus changing the drawing order without having to repopulate all of the vertices. Or, for a 3D model, you can now depth sort the Faces.
  • The Mesh Game Object now extends the SingleAlpha component and the alpha value is factored into the final alpha value per vertex during rendering. This means you can now set the whole alpha across the Mesh using the standard setAlpha methods. But, if you wish to, you can still control the alpha on a per-vertex basis as well.
  • The Mesh renderer will now check to see if the pipeline capacity has been exceeded for every Face added, allowing you to use Meshes with vertex counts that exceed the pipeline capacity without causing runtime errors.
  • You can now supply just a single numerical value as the colors parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the color for all vertices created.
  • You can now supply just a single numerical value as the alphas parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the alpha for all vertices created.
  • Mesh.debugGraphic is a new property that holds the debug Graphics instance reference.
  • Mesh.debugCallback is a new property that holds the debug render callback.
  • Mesh.renderDebugVerts is a new method that acts as the default render callback for setDebug if none is provided.
  • Mesh.preDestroy is a new method that will clean-up the Mesh arrays and debug references on destruction.
  • Mesh.isDirty is a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically in preUpdate to avoid generating lots of math when nothing has changed.
  • The Mesh.uv array has been removed. All UV data is now bound in the Vertex instances.
  • The Mesh.colors array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.alphas array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.tintFill property is now a boolean and defaults to false.

Layer Game Object

A Layer is a special type of Game Object that acts as a Display List. You can add any type of Game Object to a Layer, just as you would to a Scene. Layers can be used to visually group together 'layers' of Game Objects:

```javascript const spaceman = this.add.sprite(150, 300, 'spaceman'); const bunny = this.add.sprite(400, 300, 'bunny'); const elephant = this.add.sprite(650, 300, 'elephant');

const layer = this.add.layer();

layer.add([ spaceman, bunny, elephant ]); ```

The 3 sprites in the example above will now be managed by the Layer they were added to. Therefore, if you then set layer.setVisible(false) they would all vanish from the display.

You can also control the depth of the Game Objects within the Layer. For example, calling the setDepth method of a child of a Layer will allow you to adjust the depth of that child within the Layer itself, rather than the whole Scene. The Layer, too, can have its depth set as well.

The Layer class also offers many different methods for manipulating the list, such as the methods moveUp, moveDown, sendToBack, bringToTop and so on. These allow you to change the display list position of the Layers children, causing it to adjust the order in which they are rendered. Using setDepth on a child allows you to override this.

Layers can have Post FX Pipelines set, which allows you to easily enable a post pipeline across a whole range of children, which, depending on the effect, can often be far more efficient that doing so on a per-child basis.

Layers have no position or size within the Scene. This means you cannot enable a Layer for physics or input, or change the position, rotation or scale of a Layer. They also have no scroll factor, texture, tint, origin, crop or bounds.

If you need those kind of features then you should use a Container instead. Containers can be added to Layers, but Layers cannot be added to Containers.

However, you can set the Alpha, Blend Mode, Depth, Mask and Visible state of a Layer. These settings will impact all children being rendered by the Layer.

BitmapText Game Object

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has to work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.
  • You can now use setMaxWidth on DynamicBitmapText, which wasn't previously possible. Fix #4997 (thanks @AndreaBoeAbrahamsen)

Quad Game Object Removed

The Quad Game Object has been removed from v3.50.0.

You can now create your own Quads easily using the new Geom.Mesh.GenerateGridVerts function, which is far more flexible than the old quads were.

Animation API - New Features, API Changes and Bug Fixes

If you use Animations in your game, please read the following important API changes in 3.50:

The Animation API has had a significant overhaul to improve playback handling. Instead of just playing an animation based on its global key, you can now supply a new PlayAnimationConfig object instead, which allows you to override any of the default animation settings, such as duration, delay and yoyo (see below for the full list). This means you no longer have to create lots of duplicate animations just to change properties such as duration, and can now set them dynamically at run-time as well.

  • The Animation class no longer extends EventEmitter, as it no longer emits any events directly. This means you cannot now listen for events directly from an Animation instance. All of the events are now dispatched by the Game Objects instead.
  • All of the SPRITE_ANIMATION_KEY events have been removed. Instead, please use the new events which all carry the frameKey parameter, which can be used to handle frame specific events. The only exception to this is ANIMATION_COMPLETE_KEY, which is a key specific version of the completion event.
  • ANIMATION_UPDATE_EVENT is a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.
  • ANIMATION_STOP_EVENT is a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of the stop methods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)
  • The Game Object Component.Animation component has been renamed to AnimationState and has moved namespace. It's now in Phaser.Animations instead of GameObjects.Components to help differentiate it from the Animation class when browsing the documentation.
  • The play, playReverse, playAfterDelay, playAfterRepeat and chain Sprite and Animation Component methods can now all take a Phaser.Types.Animations.PlayAnimationConfig configuration object, as well as a string, as the key parameter. This allows you to override any default animation setting with those defined in the config, giving you far greater control over animations on a Game Object level, without needing to globally duplicate them.
  • AnimationState.create is a new method that allows you to create animations directly on a Sprite. These are not global and never enter the Animation Manager, instead residing within the Sprite itself. This allows you to use the same keys across both local and global animations and set-up Sprite specific local animations.
  • AnimationState.generateFrameNumbers is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • AnimationState.generateFrameNames is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • All playback methods: play, playReverse, playAfterDelay and playAfterRepeat will now check to see if the given animation key exists locally on the Sprite first. If it does, it's used, otherwise it then checks the global Animation Manager for the key instead.
  • AnimationState.skipMissedFrames is now used when playing an animation, allowing you to create animations that run at frame rates far exceeding the refresh rate, or that will update to the correct frame should the game lag. Feature #4232 (thanks @colorcube)
  • AnimationManager.addMix is a new method that allows you to create mixes 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.
  • AnimationManager.getMix is a new method that will return the mix duration between the two given animations.
  • AnimationManager.removeMix is a new method that will remove the mixture between either two animations, or all mixtures for the given animation.
  • AnimationState.remove is a new method that will remove a locally stored Animation instance from a Sprite.
  • AnimationState.get is a new method that will return a locally stored Animation instance from the Sprite.
  • AnimationState.exists is a new method that will check if a locally stored Animation exists on the Sprite.
  • The internal AnimationState.remove method has been renamed to globalRemove.
  • AnimationState.textureManager is a new property that references the global Texture Manager.
  • AnimationState.anims is a new property that contains locally created Animations in a Custom Map.
  • AnimationState.play and Sprite.play no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • AnimationState.playReverse and Sprite.playReverse no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • The AnimationState.delayedPlay method has been renamed to playAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration.
  • The AnimationState.stopOnRepeat method has been renamed to stopAfterRepeat
  • The AnimationState.getCurrentKey method has been renamed to getName.
  • AnimationState.getFrameName is a new method that will return the key of the current Animation Frame, if an animation has been loaded.
  • AnimationState.playAfterDelay and Sprite.playAfterDelay are new methods that will play the given animation after the delay in ms expires.
  • AnimationState.playAfterRepeat and Sprite.playAfterRepeat are new methods that will play the given animation after the current animation finishes repeating. You can also specify the number of repeats allowed left to run.
  • The AnimationState.chain method is now available on the Sprite class.
  • The AnimationState.stopAfterDelay method is now available on the Sprite class.
  • The AnimationState.stopAfterRepeat method is now available on the Sprite class.
  • The AnimationState.stopOnFrame method is now available on the Sprite class.
  • AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser. Please see the comprehensive documentation for this method for full details on how to do this.
  • AnimationState now handles all of the loading of the animation. It no longer has to make calls out to the Animation Manager or Animation instance itself and will load the animation data directly, replacing as required from the optional PlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.
  • The PlayAnimationConfig.frameRate property lets you optionally override the animation frame rate.
  • The PlayAnimationConfig.duration property lets you optionally override the animation duration.
  • The PlayAnimationConfig.delay property lets you optionally override the animation delay.
  • The PlayAnimationConfig.repeat property lets you optionally override the animation repeat counter.
  • The PlayAnimationConfig.repeatDelay property lets you optionally override the animation repeat delay value.
  • The PlayAnimationConfig.yoyo property lets you optionally override the animation yoyo boolean.
  • The PlayAnimationConfig.showOnStart property lets you optionally override the animation show on start value.
  • The PlayAnimationConfig.hideOnComplete property lets you optionally override the animation hide on complete value.
  • The PlayAnimationConfig.startFrame property lets you optionally set the animation frame to start on.
  • The PlayAnimationConfig.timeScale property lets you optionally set the animation time scale factor.
  • AnimationState.delayCounter is a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animation START events fire. Fix #4426 (thanks @bdaenen)
  • AnimationState.hasStarted is a new boolean property that allows you to tell if the current animation has started playing, or is still waiting for a delay to expire.
  • AnimationState.showOnStart is a new boolean property that controls if the Game Object should have setVisible(true) called on it when the animation starts.
  • AnimationState.hideOnComplete is a new boolean property that controls if the Game Object should have setVisible(false) called on it when the animation completes.
  • The AnimationState.chain method docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does!
  • The AnimationState.setDelay method has been removed. It never actually worked and you can now perform the same thing by calling either playAfterDelay or setting the delay property in the play config.
  • The AnimationState.getDelay method has been removed. You can now read the delay property directly.
  • The AnimationState.setRepeat method has been removed. You can achieve the same thing by setting the repeat property in the play config, or adjusting the public repeatCounter property if the animation has started.
  • AnimationState.handleStart is a new internal private method that handles the animation start process.
  • AnimationState.handleRepeat is a new internal private method that handles the animation repeat process.
  • AnimationState.handleStop is a new internal private method that handles the animation stop process.
  • AnimationState.handleComplete is a new internal private method that handles the animation complete process.
  • AnimationState.emitEvents is a new internal private method that emits animation events, cutting down on duplicate code.
  • The AnimationState.restart method has a new optional boolean parameter resetRepeats which controls if you want to reset the repeat counter during the restart, or not.
  • Animation.getTotalFrames is a new method that will return the total number of frames in the animation. You can access it via this.anims.currentAnim.getTotalFrames from a Sprite.
  • Animation.calculateDuration is a new method that calculates the duration, frameRate and msPerFrame for a given animation target.
  • The BuildGameObjectAnimation function now uses the PlayAnimationConfig object to set the values.
  • Sprite.playReverse is a new method that allows you to play the given animation in reverse on the Sprite.
  • Sprite.playAfterDelay is a new method that allows you to play the given animation on the Sprite after a delay.
  • Sprite.stop is a new method that allows you to stop the current animation on the Sprite.
  • AnimationManager.load has been removed as it's no longer required.
  • AnimationManager.staggerPlay has been fixed so you can now pass in negative stagger values.
  • AnimationManager.staggerPlay has a new optional boolean parameter staggerFirst, which allows you to either include or exclude the first child in the stagger calculations.
  • The Animation.completeAnimation method has been removed as it's no longer required.
  • The Animation.load method has been removed as it's no longer required.
  • The Animation.setFrame method has been removed as it's no longer required.
  • The Animation.getFirstTick method has no longer needs the includeDelay parameter, as it's handled by AnimationState now.
  • The Animation.getFrames method has a new optional boolean parameter sortFrames which will run a numeric sort on the frame names after constructing them, if a string-based frame is given.
  • Types.Animations.Animation has a new boolean property sortFrames, which lets Phaser numerically sort the generated frames.
  • AnimationState.timeScale is a new public property that replaces the old private _timeScale property.
  • AnimationState.delay is a new public property that replaces the old private _delay property.
  • AnimationState.repeat is a new public property that replaces the old private _repeat property.
  • AnimationState.repeatDelay is a new public property that replaces the old private _repeatDelay property.
  • AnimationState.yoyo is a new public property that replaces the old private _yoyo property.
  • AnimationState.inReverse is a new public property that replaces the old private _reverse property.
  • AnimationState.startAnimation is a new public method that replaces the old private _startAnimation method.
  • The AnimationState.getProgress method has been fixed so it will return correctly if the animation is playing in reverse.
  • The AnimationState.globalRemove method will now always be called when an animation is removed from the global Animation Manager, not just once.
  • The AnimationState.getRepeat method has now been removed. You can get the value from the repeat property.
  • The AnimationState.setRepeatDelay method has now been removed. You can set the value using the repeatDelay config property, or changing it at run-time.
  • AnimationState.complete is a new method that handles the completion in animation playback.
  • The AnimationState.setTimeScale method has now been removed. You can set the value using the timeScale config property, or changing it at run-time.
  • The AnimationState.getTimeScale method has now been removed. You can read the value using the timeScale property.
  • The AnimationState.getTotalFrames method has been fixed and won't error if called when no animation is loaded.
  • The AnimationState.setYoyo method has now been removed. You can set the value using the yoyo config property, or changing it at run-time.
  • The AnimationState.getYoyo method has now been removed. You can read the value using the yoyo property.
  • The AnimationState.stopAfterRepeat method now has an optional parameter repeatCount, so you can tell the animation to stop after a specified number of repeats, not just 1.
  • When playing an animation in reverse, if it reached the first frame and had to repeat, it would then jump to the frame before the final frame and carry on, skipping out the final frame.
  • The AnimationState.updateFrame method has now been removed. Everything is handled by setCurrentFrame instead, which removes one extra step out of the update process.
  • GenerateFrameNames will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers would include the __BASE frame by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.
  • GenerateFrameNumbers can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.
  • GenerateFrameNames can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.

Tilemap - New Features, API Changes and Bug Fixes

There are three large changes to Tilemaps in 3.50. If you use tilemaps, you must read this section:

1) The first change is that there are no longer DynamicTilemapLayer and StaticTilemapLayer classes. They have both been removed and replaced with the new TilemapLayer class. This new class consolidates features from both and provides a lot cleaner API experience, as well as speeding up internal logic.

In your game where you use map.createDynamicLayer or map.createStaticLayer replace it with map.createLayer instead.

2) The second change is that the Tilemap system now supports isometric, hexagonal and staggered isometric map types, along with the previous orthogonal format, thanks to a PR from @svipal. You can now export maps using any of these orientations from the Tiled Map Editor and load them into Phaser using the existing tilemap loading API. No further changes need to take place in the way your maps are loaded.

3) The Tilemap.createFromObjects method has been overhauled to make it much more useful. The method signature has changed and it now takes a new CreateFromObjectLayerConfig configuration object, or an array of them, which allows much more fine-grained control over which objects in the Tiled Object Layers are converted and what they are converted to. Previously it could only convert to Sprites, but you can now pass in a custom class, filter based on id, gid or name, even provide a Container to add the created Game Objects to. Please see the new documentation for this method and the config object for more details. Fix #3817 #4613 (thanks @georgzoeller @Secretmapper)

  • The Tilemap.createDynamicLayer method has been renamed to createLayer.
  • The Tilemap.createStaticLayer method has been removed. Use createLayer instead.
  • The Tilemap.createBlankDynamicLayer method has been renamed to createBlankLayer.
  • The Tilemap.convertLayerToStatic method has been removed as it is no longer required.
  • The TilemapLayerWebGLRenderer function will no longer iterate through the layer tilesets, drawing tiles from only that set. Instead all it does now is iterate directly through only the tiles. This allows it to take advantage of the new Multi Texturing pipeline and also draw multi-tileset isometric layers correctly.
  • Phaser.Types.Tilemaps.TilemapOrientationType is a new type def that holds the 4 types of map orientation now supported.
  • The Tile.updatePixelXY method now updates the tile XY position based on map type.
  • ParseTilesets will now correctly handle non-consecutive tile IDs. It also now correctly sets the maxId property, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)
  • Tilemap.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • LayerData.orientation is a new property that holds the tilemap layers orientation constant.
  • LayerData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • MapData.orientation is a new property that holds the tilemap layers orientation constant.
  • MapData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • Tilemaps.Components.HexagonalWorldToTileY is a new function that converts a world Y coordinate to hexagonal tile Y coordinate.
  • Tilemaps.Components.StaggeredWorldToTileY is a new function that converts a world Y coordinate to staggered tile Y coordinate.
  • Tilemaps.Components.HexagonalWorldToTileXY is a new function that converts world coordinates to hexagonal tile coordinates.
  • Tilemaps.Components.IsometricWorldToTileXY is a new function that converts world coordinates to isometric tile coordinates.
  • Tilemaps.Components.StaggeredWorldToTileXY is a new function that converts world coordinates to staggered tile coordinates.
  • Tilemaps.Components.HexagonalTileToWorldY is a new function that converts a hexagonal Y coordinate to a world coordinate.
  • Tilemaps.Components.StaggeredTileToWorldY is a new function that converts a staggered Y coordinate to a world coordinate.
  • Tilemaps.Components.HexagonalTileToWorldXY is a new function that converts hexagonal tile coordinates to world coordinates.
  • Tilemaps.Components.IsometricTileToWorldXY is a new function that converts isometric tile coordinates to world coordinates.
  • Tilemaps.Components.StaggeredTileToWorldXY is a new function that converts staggered tile coordinates to world coordinates.
  • Tilemaps.Components.GetTileToWorldXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldXXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetCullTilesFunction is a new function that returns the correct culling function to use.
  • Tilemaps.Components.HexagonalCullTiles is a new function that culls tiles in a hexagonal map.
  • Tilemaps.Components.StaggeredCullTiles is a new function that culls tiles in a staggered map.
  • Tilemaps.Components.IsometricCullTiles is a new function that culls tiles in a isometric map.
  • Tilemaps.Components.CullBounds is a new function that calculates the cull bounds for an orthogonal map.
  • Tilemaps.Components.HexagonalCullBounds is a new function that calculates the cull bounds for a hexagonal map.
  • Tilemaps.Components.StaggeredCullBounds is a new function that calculates the cull bounds for a staggered map.
  • Tilemaps.Components.RunCull is a new function that runs the culling process from the combined bounds and tilemap.
  • Tilemap._convert is a new internal private hash of tilemap conversion functions used by the public API.
  • The Tilemap._isStaticCall method has been removed and no Tilemap methods now check this, leading to faster execution.
  • The Arcade Physics Sprites vs. Tilemap Layers flow has changed. Previously, it would iterate through a whole bunch of linked functions, taking lots of jumps in the process. It now just calls the GetTilesWithinWorldXY component directly, saving lots of overhead.
  • The method Tilemap.weightedRandomize has changed so that the parameter weightedIndexes is now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional.
  • The method TilemapLayer.weightedRandomize has changed so that the parameter weightedIndexes is now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional.

Update List - New Features, API Changes and Bug Fixes

The way in which Game Objects add themselves to the Scene Update List has changed. Instead of being added by the Factory methods, they will now add and remove themselves based on the new ADDED_TO_SCENE and REMOVED_FROM_SCENE events. This means, you can now add Sprites directly to a Container, or Group, and they'll animate properly without first having to be part of the Update List. The full set of changes and new features relating to this follow:

  • GameObjects.Events.ADDED_TO_SCENE is a new event, emitted by a Game Object, when it is added to a Scene, or a Container that is part of the Scene.
  • GameObjects.Events.REMOVED_FROM_SCENE is a new event, emitted by a Game Object, when it is removed from a Scene, or a Container that is part of the Scene.
  • Scenes.Events.ADDED_TO_SCENE is a new event, emitted by a Scene, when a new Game Object is added to the display list in the Scene, or a Container that is on the display list.
  • Scenes.Events.REMOVED_FROM_SCENE is a new event, emitted by a Scene, when it a Game Object is removed from the display list in the Scene, or a Container that is on the display list.
  • GameObject.addedToScene is a new method that custom Game Objects can use to perform additional set-up when a Game Object is added to a Scene. For example, Sprite uses this to add itself to the Update List.
  • GameObject.removedFromScene is a new method that custom Game Objects can use to perform additional tear-down when a Game Object is removed from a Scene. For example, Sprite uses this to remove themselves from the Update List.
  • Game Objects no longer automatically remove themselves from the Update List during preDestroy. This should be handled directly in the removedFromScene method now.
  • The Container will now test to see if any Game Object added to it is already on the display list, or not, and emit its ADDED and REMOVED events accordingly. Fix #5267 #3876 (thanks @halgorithm @mbpictures)
  • DisplayList.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • DisplayList.addChildCallback is a new method that overrides the List callback and fires the new ADDED events.
  • DisplayList.removeChildCallback is a new method that overrides the List callback and fires the new REMOVED events.
  • GameObjectCreator.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • GameObjectFactory.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • ProcessQueue.checkQueue is a new boolean property that will make sure only unique objects are added to the Process Queue.
  • The Update List now uses the new checkQueue property to ensure no duplicate objects are on the active list.
  • DOMElementFactory, ExternFactory, ParticleManagerFactor, RopeFactory and SpriteFactory all no longer add the objects to the Update List, this is now handled by the ADDED events instead.
  • Sprite, Rope, ParticleEmitterManager, Extern and DOMElement now all override the addedToScene and removedFromScene callbacks to handle further set-up tasks.

Input Manager and Mouse Manager - New Features, API Changes and Bug Fixes

  • ScaleManager.refresh is now called when the Game.READY event fires. This fixes a bug where the Scale Manager would have the incorrect canvas bounds, because they were calculated before a previous canvas was removed from the DOM. Fix #4862 (thanks @dranitski)
  • The Game Config property inputMouseCapture has been removed, as this is now split into 3 new config options:
  • inputMousePreventDefaultDown is a new config option that allows you to control preventDefault calls specifically on mouse down events. Set it via input.mouse.preventDefaultDown in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultUp is a new config option that allows you to control preventDefault calls specifically on mouse up events. Set it via input.mouse.preventDefaultUp in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultMove is a new config option that allows you to control preventDefault calls specifically on mouse move events. Set it via input.mouse.preventDefaultMove in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultWheel is a new config option that allows you to control preventDefault calls specifically on mouse wheel events. Set it via input.mouse.preventDefaultWheel in the Game Config. It defaults to true, the same as the previous capture property did.
  • The MouseManager.capture property has been removed, as this is now split into 3 new config options (see below)
  • MouseManager.preventDefaultDown is a new boolean property, set via the inputMousePreventDefaultDown config option that allows you to toggle capture of mouse down events at runtime.
  • MouseManager.preventDefaultUp is a new boolean property, set via the inputMousePreventDefaultUp config option that allows you to toggle capture of mouse up events at runtime.
  • MouseManager.preventDefaultMove is a new boolean property, set via the inputMousePreventDefaultMove config option that allows you to toggle capture of mouse move events at runtime.
  • MouseManager.preventDefaultWheel is a new boolean property, set via the inputMousePreventDefaultWheel config option that allows you to toggle capture of mouse wheel at runtime.
  • In the MouseManager the up, down and move events are no longer set as being passive if captured. Over, Out, Wheel and the Window level Down and Up events are always flagged as being passive. Wheel events are non-passive if capturing is enabled.
  • The GamepadPlugin will now call refreshPads as part of its start process. This allows you to use Gamepads across multiple Scenes, without having to wait for a connected event from each one of them. If you've already had a connected event in a previous Scene, you can now just read the pads directly via this.input.gamepad.pad1 and similar. Fix #4890 (thanks @Sytten)
  • Shutting down the Gamepad plugin (such as when sleeping a Scene) no longer calls GamepadPlugin.disconnectAll, but destroying it does.
  • Gamepad._created is a new private internal property that keeps track of when the instance was created. This is compared to the navigator timestamp in the update loop to avoid event spamming. Fix #4890.
  • Pointer.down will now check if the browser is running under macOS and if the ctrl key was also pressed, if so, it will flag the down event as being a right-click instead of a left-click, as per macOS conventions. Fix #4245 (thanks @BigZaphod)
  • When destroying an interactive Game Object that had useHandCursor enabled, it would reset the CSS cursor to default, even if the cursor wasn't over that Game Object. It will now only reset the cursor if it's over the Game Object being destroyed. Fix #5321 (thanks @JstnPwll)
  • The InputPlugin.shutdown method will now reset the CSS cursor, in case it was set by any Game Objects in the Scene that have since been destroyed.
  • The InputPlugin.processOverEvents has had a duplicate internal loop removed from it (thanks KingCosmic)

Tint Component Updates and resulting Shader Changes

Phaser has had the ability to apply an additive tint to a Game Object since the beginning, and gained 'filled tints', with and without texture alpha, in v3.11. While this was handy, it introduced a 3-way if-else condition to the shaders to handle the different modes. Plus, setting tint colors was also generating rgb order Float32 color values for each Game Object, making reading those colors back again difficult (as they'd return in BGR order).

This has all changed in 3.50, as outlined below. Tint values are now used directly in the shader and don't pass through a color conversion function first. Lots of private properties have been removed and the shaders no longer have a 3-way if-else block. All of this means improved performance and a slight reduction in memory overhead.

  • Tint.tintTopLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTL which has now been removed.
  • Tint.tintTopRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTR which has now been removed.
  • Tint.tintBottomLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBL which has now been removed.
  • Tint.tintBottomRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBR which has now been removed.
  • The property Tint._isTinted has been removed as it's no longer required.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they now read the color value as outTint.bgr instead of outTint.rgb. This allows the colors to remain in RGB order within the Tint component.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they no longer have a 3-way check on the outTintEffect value.
  • The Multi Pipeline, Bitmap Text, Render Texture, Text, TileSprite and Camera now all read the tint values from the public properties instead of the private _tintTL etc ones. They also now set the tintEffect value directly from the tintFill property, removing another conditional check.
  • The function GetColorFromValue has been removed as it's no longer used internally.
  • The Rope.tintFill property is now a boolean, not an integer, and can no longer take 2 as a value for a complete fill. Instead, you should provide a solid color texture with no alpha.
  • As a result of the change to the shader, all uses of the WebGL Util function getTintAppendFloatAlphaAndSwap have been replaced with getTintAppendFloatAlpha instead.
  • As a result of the change to the shader, the Multi Pipeline now uses the WebGLRenderer.whiteTexture and tintEffect mode of 1 by default, instead of mode 2 (which has been removed) and a transparent texture. This ensures Graphics and Shapes objects still render correctly under the new smaller shader code.
  • WebGLRenderer.whiteTexture is a new property that is a reference to a pure white 4x4 texture that is created during Boot by the Texture Manager. The Graphics Pipeline uses this internally for all geometry fill rendering.
  • The TextureManager now generates a new texture with the key __WHITE during its boot process. This is a pure white 4x4 texture used by the Graphics pipelines.
  • Config.images.white is a new Game Config property that specifies the 4x4 white PNG texture used by Graphics rendering. You can override this via the config, but only do so if needed.

Arcade Physics - New Features, API Changes and Bug Fixes

Prior to v3.50 an Arcade Physics Body could be one of two states: immovable, or movable. An immovable body could not receive any impact from another Body. If something collided with it, it wouldn't even separate to break free from the collision (the other body had to take the full separation value). It was intended for objects such as platforms, ground or walls, there they absolutely shouldn't move under any circumstances. As a result, two immovable bodies could never be collided together. While this worked for scenery-like items, it didn't work if you required maybe 2 players who could collide with each other, but should never be able to push one another. As of 3.50 all physics bodies now have a new property pushable that allows this. A pushable body can share separation with its collider, as well as take on mass-based velocity from the impact. A non-pushable body will behave differently depending on what it collides with. For example, a pushable body hitting a non-pushable (or immovable) body will rebound off it.

  • The Arcade Physics Body class has a new boolean property pushable (true, by default). This allows you to set if a Body can be physically pushed by another Body, or not. Fix #4175 #4415 (thanks @inmylo @CipSoft-Components)
  • Body.setPushable is a new chainable method that allows you to set the pushable state of a Body.
  • Arcade.Components.Pushable is a new component, inherited by the standard Arcade Physics Image and Sprite classes.
  • Bodies will now check to see if they are blocked in the direction they're being pushed, before resolving the collision. This helps stop some bodies from being pushed into other objects.
  • Bodies will now check which direction they were moving and separate accordingly. This helps stop some bodies from being pushed into other objects.
  • ArcadePhysics.disableUpdate is a new method that will prevent the Arcade Physics World update method from being called when the Scene updates. By disabling it, you're free to call the update method yourself, passing in your own delta and time values.
  • ArcadePhysics.enableUpdate is a new method that will make the Arcade Physics World update in time with the Scene update. This is the default, so only call this if you have specifically disabled it previously.
  • ArcadeWorldConfig.customUpdate is a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. If true the World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)
  • Physics.Arcade.Body.setCollideWorldBounds now has a new optional parameter onWorldBounds which allows you to enable the Body's onWorldBounds property in the same call (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityX is a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityY is a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)
  • The PhysicsGroup config now has two new optional properties maxVelocityX and maxVelocityY which allows you to set the maximum velocity on bodies added to the Group (thanks @samme)
  • The Arcade.Body.resetFlags method has a new optional boolean parameter clear. If set, it clears the wasTouching flags on the Body. This happens automatically when Body.reset is called. Previous to this, the flags were not reset until the next physics step (thanks @samme)
  • Physics.Arcade.ProcessX is a new set of functions, called by the SeparateX function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Physics.Arcade.ProcessY is a new set of functions, called by the SeparateY function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Arcade.Body.center values were incorrect after collisions with the world bounds or (for rectangular bodies) after collisions with another body. The body center is now updated after those separations (thanks @samme)
  • The Arcade Physics WORLD_STEP event now has a new parameter: the delta argument (thanks @samme)
  • The Arcade Body drag property has been redefined when damping is used and scales the damping multiplier by the physics step delta. Drag is now the velocity retained after 1 second instead of after 1 step, when damping is used. This makes damping consistent for different physics step rates and more accurate when fixedStep is off. If you use drag you will need to change any existing drag values to get the same effects as before. Convert drag to drag ^ 60 or drag ^ fps if you use a different step rate (thanks @samme)

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.
  • You can now use this.renderer from within a Scene, as it's now a Scene-level property and part of the Injection Map.
  • Clock.addEvent can now take an existing TimerEvent object, as well as a config object. If a TimerEvent is given it will be removed from the Clock, reset and then added. This allows you to pool TimerEvents rather than constantly create and delete them. Fix #4115 (thanks @jcyuan)
  • Clock.removeEvent is a new method that allows you to remove a TimerEvent, or an array of them, from all internal lists of the current Clock.
  • Group.getMatching is a new method that will return any members of the Group that match the given criteria, such as getMatching('visible', true) (thanks @atursams)
  • Utils.Array.SortByDigits is a new function that takes the given array of strings and runs a numeric sort on it, ignoring any non-digits.
  • GroupCreateConfig, which is used when calling Group.createMultiple or Group.createFromConfig, can now accept the following new properties: setOrigin: { x, y, stepX, stepY } which are applied to the items created by the Group.
  • Transform.copyPosition is a new method that will copy the position from the given object to the Game Object (thanks @samme)
  • The Text.MeasureText function, which is used to calculate the ascent and descent of Text Game Objects whenever the style, or font size, is changed, has been updated to use the new actualBoundingBoxAscent functions present in modern browsers. This allows for significantly faster ascent calculations than previously. Older browsers, such as IE, will still fall back (thanks @rexrainbow)
  • GameObjects.GetCalcMatrix is a new function that is used to calculate the transformed Game Object matrix, based on the given Game Object, Camera and Parent. This function is now used by the following Game Objects: BitmapText (Static and Dynamic), Graphics, Extern, Mesh, Rope, Shader, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. This dramatically reduces the amount of duplicate code across the API.
  • Utils.Array.Matrix.Translate is a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.
  • Vertor3.addScale is a new method that will add the given vector and multiply it in the process.
  • When defining the ease used with a Particle Emitter you can now set easeParams in the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh)
  • BitmapMask.createMask is a new method that will internally create the WebGL textures and framebuffers required for the mask. This is now used by the constructor and if the context is lost. It now also clears any previous textures/fbos that may have been created first, helping prevent memory leaks.
  • BitmapMask.clearMask will delete any WebGL textures or framebuffers the mask is using. This is now called when the mask is destroyed, or a new mask is created upon it.
  • Quaternion now has a new property onChangeCallback which, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.
  • The Quaternion.set method has a new optional boolean parameter update (defaults to true), which will call the onChangeCallback if set.
  • Quaternion.setFromEuler is a new method that will set the quaternion from the given Euler object, optionally calling the onChangeCallback in the process.
  • Quaternion.setFromRotationMatrix is a new method that will set the rotation of the quaternion from the given Matrix4.
  • Vector3.setFromMatrixPosition is a new method that will set the components of the Vector3 based on the position of the given Matrix4.
  • Vector3.setFromMatrixColumn is a new method that will set the components of the Vector3 based on the specified Matrix4 column.
  • Vector3.fromArray is a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.
  • Vector3.min is a new method that will set the components of the Vector3 based on the Main.min between it and the given Vector3.
  • Vector3.max is a new method that will set the components of the Vector3 based on the Main.max between it and the given Vector3.
  • Vector3.addVectors is a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.
  • Vector3.addScalar is a new method that will multiply the components of the Vector3 by the scale value given.
  • Vector3.applyMatrix3 is a new method that will take a Matrix3 and apply it to the Vector3.
  • Vector3.applyMatrix4 is a new method that will take a Matrix4 and apply it to the Vector3.
  • Vector3.projectViewMatrix is a new method that multiplies the Vector3 by the given view and projection matrices.
  • Vector3.unprojectViewMatrix is a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.
  • Matrix4.setValues is a new method that allows you to set all of the matrix components individually. Most internal methods now use this.
  • Matrix.multiplyToMat4 is a new method that multiplies a Matrix4 by the given src Matrix4 and stores the results in the out Matrix4.
  • Matrix4.fromRotationXYTranslation is a new method that takes the rotation and position vectors and builds this Matrix4 from them.
  • Matrix4.getMaxScaleOnAxis is a new method that will return the maximum axis scale from the Matrix4.
  • Matrix4.lookAtRH is a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.
  • Matrix4.transform is a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.
  • Matrix4.multiplyMatrices is a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.
  • Matrix4.premultiply is a new method that takes a Matrix4 and multiplies it by the current Matrix4.
  • Matrix4.getInverse is a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.
  • CameraManager.getVisibleChildren is a new method that is called internally by the CameraManager.render method. It filters the DisplayList, so that Game Objects that pass the willRender test for the given Camera are added to a sub-list, which is then passed to the renderer. This avoids the renderer having to do any checks on the children, it just renders each one in turn.
  • Physics.Arcade.Body.setDamping is a new method that allows you to set the useDamping property of a Body in a chainable way. Fix #5352 (thanks @juanitogan)
  • The GameObjects.Graphics.fillGradientStyle method can now accept a different alpha value for each of the fill colors. The default is still 1. If you only provide a single alpha, it'll be used for all colors. Fix #5044 (thanks @zhangciwu)
  • Types.Core.PipelineConfig is a new configuration object that you can set in the Game Config under the pipeline property. It allows you to define custom WebGL pipelines as part of the Game Config, so they're automatically installed and ready for use by all Scenes in your game. You can either set the pipeline object, or set it under the render sub-config.
  • Utils.Object.DeepCopy is a new function that will recursively deep copy an array of object.
  • Time.TimerEvent.getRemaining is a new method that returns the time interval until the next iteration of the Timer Event (thanks @samme)
  • Time.TimerEvent.getRemainingSeconds is a new method that returns the time interval until the next iteration of the Timer Event in seconds (thanks @samme)
  • Time.TimerEvent.getOverallRemaining is a new method that returns the time interval until the last iteration of the Timer Event (thanks @samme)
  • Time.TimerEvent.getOverallRemainingSeconds is a new method that returns the time interval until the last iteration of the Timer Event in seconds (thanks @samme)
  • GameObjects.Video.loadMediaStream is a new method that allows you to hook a Video Game Object up to a Media Stream, rather than a URL, allowing you to stream video from a source such as a webcam (thanks @pirateksh)
  • Display.Color.ColorSpectrum is a new function that will return an array of 1024 Color Object elements aligned in a Color Spectrum layout, where the darkest colors have been omitted.
  • AsepriteFile is a new File Type for the Loader that allows you to load Aseprite images and animation data for use with the new Aseprite animation features. You can call this via this.load.asesprite(png, json).
  • GameObject.displayList is a new property that contains a reference to the Display List to which the Game Object has been added. This will typically either by the Display List owned by a Scene, or a Layer Game Object. You should treat this property as read-only.
  • The Shader Game Object now supports being able to use a Render Texture as a sampler2D texture on the shader #5423 (thanks @ccaleb)
  • BaseSound.pan, HTMLAudioSound.pan and WebAudioSound.pan are new properties that allow you to get or set the pan value of a sound, a value between -1 (full left pan) and 1 (full right pan). Note that pan only works under Web Audio, but the property and event still exists under HTML5 Audio for compatibility (thanks @pi-kei)
  • WebAudioSound.setPan is a new method that allows you to set the pan of the sound. A value between -1 (full left pan) and 1 (full right pan) (thanks @pi-kei)
  • Sound.Events.PAN is a new event dispatched by both Web Audio and HTML5 Audio Sound objects when their pan changes (thanks @pi-kei)

ColorMatrix

  • Phaser.Display.ColorMatrix is a new class that allows you to create and manipulate a 5x4 color matrix, which can be used by shaders or graphics operations.
  • The ColorMatrix.set method allows you to set the values of a ColorMatrix.
  • The ColorMatrix.reset method will reset the ColorMatrix to its default values.
  • The ColorMatrix.getData method will return the data in the ColorMatrix as a Float32Array, useful for setting in a shader uniform.
  • The ColorMatrix.brightness method lets you set the brightness of the ColorMatrix.
  • The ColorMatrix.saturate method lets you set the saturation of the ColorMatrix.
  • The ColorMatrix.desaturate method lets you desaturate the colors in the ColorMatrix.
  • The ColorMatrix.hue method lets you rotate the hues of the ColorMatrix by the given amount.
  • The ColorMatrix.grayscale method converts the ColorMatrix to grayscale.
  • The ColorMatrix.blackWhite method converts the ColorMatrix to black and whites.
  • The ColorMatrix.contrast method lets you set the contrast of the ColorMatrix.
  • The ColorMatrix.negative method converts the ColorMatrix to negative values.
  • The ColorMatrix.desaturateLuminance method applies a desaturated luminance to the ColorMatrix.
  • The ColorMatrix.sepia method applies a sepia tone to the ColorMatrix.
  • The ColorMatrix.night method applies a night time effect to the ColorMatrix.
  • The ColorMatrix.lsd method applies a trippy color effect to the ColorMatrix.
  • The ColorMatrix.brown method applies a brown tone to the ColorMatrix.
  • The ColorMatrix.vintagePinhole method applies a vintage pinhole color effect to the ColorMatrix.
  • The ColorMatrix.kodachrome method applies a kodachrome color effect to the ColorMatrix.
  • The ColorMatrix.technicolor method applies a technicolor color effect to the ColorMatrix.
  • The ColorMatrix.polaroid method applies a polaroid color effect to the ColorMatrix.
  • The ColorMatrix.shiftToBGR method shifts the values of the ColorMatrix into BGR order.
  • The ColorMatrix.multiply method multiplies two ColorMatrix data sets together.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Earcut has now been exposed and is available via Geom.Polygon.Earcut and is fully documented.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.
  • Pointer.downTime now stores the event timestamp of when the first button on the input device was pressed down, not just when button 1 was pressed down.
  • Pointer.upTime now stores the event timestamp of when the final depressed button on the input device was released, not just when button 1 was released.
  • The Pointer.getDuration method now uses the new Pointer downTime and upTime values, meaning it will accurately report the duration of when any button is being held down, not just the primary one. Fix #5112 (thanks @veleek)
  • The BaseShader default vertex shader now includes the outTexCoord vec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok)
  • When using the GameObjectCreator for Containers you can now specify the children property in the configuration object.
  • Textures.Parsers.JSONHash will now perform a hasOwnProperty check when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes from JSON.parse. Fix #4768 (thanks @RollinSafary)
  • The Camera3D Plugin has been rebuilt for Phaser 3.50 and the webpack config updated. This plugin is now considered deprecated and will not be updated beyond this release.
  • Tween.seek will no longer issue a console warning for 'Tween.seek duration too long', it's now up to you to check on the performance of tween seeking.
  • If inputWindowEvents is set in the Game Config, then the MouseManager will now listen for the events on window.top instead of just window, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in a try/catch block, as not all sites allow access to window.top (specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow)
  • MouseManager.isTop is a new boolean read-only property that flags if the mouse event listeners were attached to window.top (true), or just window (false). By default Phaser will attempt window.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back to window in those cases and set this property to false (thanks BunBunBun)
  • Types.GameObjects.Text.GetTextSizeObject is a new type def for the GetTextSize function results.
  • Utils.Array.StableSort has been recoded. It's now based on Two-Screens stable sort 0.1.8 and has been updated to fit into Phaser better and no longer create any window bound objects. The inplace function has been removed, just call StableSort(array) directly now. All classes that used StableSort.inplace have been updated to call it directly.
  • If a Scene is paused, or sent to sleep, it will automatically call Keyboard.resetKeys. This means that if you hold a key down, then sleep or pause a Scene, then release the key and resume or wake the Scene, it will no longer think it is still being held down (thanks @samme)
  • Actions.setOrigin will now call updateDisplayOrigin on the items array, otherwise the effects can't be seen when rendering.
  • You can now set the ArcadeWorld.fixedStep property via the ArcadeWorldConfig object (thanks @samme)
  • Utils.Array.NumerArray can now accept the start and end parameters in reverse order, i.e. 10, 1 will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.
  • DataManager.Events.DESTROY is a new event that the Data Manager will listen for from its parent and then call its own destroy method when received.
  • The Quaternion class constructor will now default the values to 0,0,0,1 if they're not provided, making it an identity quaternion, rather than the 0,0,0,0 it was before.
  • You can now set the ParticleEmitter.reserve value via the emitter configuration object (thanks @vforsh)
  • Setting the pixelArt config option will now set antialiasGL to false, as well as antialias. Fix #5309 (thanks @Vegita2)
  • The Shape class now includes the ComputedSize component properties and methods directly in the class, rather than applying as a mixin. setSize is now flagged as being private, because it shouldn't be used on Shape classes, which was leading to confusion as it appeared in the public-facing API. Fix #4811 (thanks @aolsx)
  • The Loader.maxParallelDownloads value is now set to 6 if running on Android, or 32 on any other OS. This avoids net::ERR_FAILED issues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary)
  • When running an Arcade Physics overlap test against a StaticBody, it will no longer set the blocked states of the dynamic body. If you are doing a collision test, they will still be set, but they're skipped for overlap-only tests. Fix #4435 (thanks @samme)
  • The Line Game Object will now default its width and height to 1, rather than zero. This allows you to give Line objects a physics body (although you will still need to re-adjust the center of the body manually). Fix #4596 (thanks @andrewaustin)
  • Internally, the Quaternion class now has 4 new private properties: _x, _y, _z and _w and 4 new getters and setters for the public versions. It also now passes most methods via set to allow for the onChange callback to be invoked. This does not change the public-facing API.
  • Group now extends EventEmitter, allowing you to emit custom events from within a Group.
  • Device.Audio.wav now uses audio/wav as the canPlayType check string, instead of audio/wav; codecs="1", which should allow iOS13 to play wav files again.
  • In the Loader.FileTypes.TextFile config you can now override the type and cache destination for the file.
  • Loader.MultiFile will now parse the given files array and only add valid entries into the file list, allowing multifiles to now have optional file entries.
  • The ParticleEmitter.tint value is now 0xffffff (previously, it was 0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh)
  • SceneManager.start will now reset the SceneSystems.sceneUpdate reference to NOOP. This gets set back to the Scene update method again during bootScene (if it has one) and stops errors with external plugins and multi-part files that may trigger update before create has been called. Fix #4629 (thanks @Osmose)
  • Phaser.Scene.renderer is a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.
  • The CanvasRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.
  • Since iOS 13, iPads now identify as MacOS devices. A new maxTouchPoint check is now part of the Device.OS tests, stopping iPads from being flagged as desktop devices. Fix #5389 (thanks @SBCGames)
  • The BitmapMask.prevFramebuffer property has been removed as it's no longer required, due to the fbo stack in the renderer.
  • The TextureManager.addGLTexture method has been updated so that the width and height parameters are now optional. If not provided, and if available, they will be read from the given WebGLTexture instead (thanks @hexus)
  • GameObjects.Components.Depth.depthList is a new property that all Game Objects that have the Depth Component now have. It contains a reference to the List responsible for managing the depth sorting of the Game Object. This is typically the Scene Display List, but can also be a Layer. It allows the Depth component to queue a depth sort directly on the list it belongs to now, rather than just the Scene.
  • The WebAudioSoundManager will no longer try to unlock itself if the Game hasn't already booted and been added to the DOM. It will now wait for the BOOT event and unlock based on that. Fix #5439 (thanks @samme)

Bug Fixes

  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)
  • The GridAlign action didn't work if only the height parameter was set. Fix #5019 (thanks @halilcakar)
  • The Color.HSVToRGB function has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX)
  • Previously, the easeParams array within a Tweens props object, or a multi-object tween, were ignored and it was only used if set on the root Tween object. It will now work correctly set at any depth. Fix #4292 (thanks @willblackmore)
  • When using Camera.setRenderToTexture its zoom and rotation values would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok)
  • GameObjects.Shape.Grid would render a white fill even if you passed undefined as the fill color in the constructor. It now doesn't render cells if no fill color is given.
  • The onMouse events in the Input Manager didn't reset the activePointer property to the mouse, meaning on dual-input systems such as Touch Screen devices, the active pointer would become locked to whichever input method was used first. Fix #4615 #5232 (thanks @mmolina01 @JstnPwll @Legomite)
  • The Scale Managers GetScreenOrientation function will now check for window.orientation first, because iOS mobile browsers have an incomplete implementation of the Screen API, forcing us to use the window value as a priority. This means the Scale Manager will now emit orientationchange events correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu)
  • Time.Clock.addEvent can now take an instance of a TimerEvent as its parameter. Fix #5294 (thanks @samme @EmilSV)
  • GameConfig.audio now defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)
  • The Loader.path was being added to the File URL even if the URL was absolute. This is now checked for and the path is not applied unless the URL is relative (thanks @firesoft)
  • Group.getMatching would always return an empty array. It now returns matching children (thanks @samme)
  • The ParticleManagerWebGLRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in follow offsets separately. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers. Fix #5319 #5195 #4739 #4691 (thanks @vforsh @condeagustin @IvanDem @Formic)
  • The ParticleManagerCanvasRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also uses setToContext internally. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers, or having the Camera zoomed, running under Canvas. Fix #4908 #4531 #4131 (thanks @smjnab @SirLink @jhooper04)
  • The Graphics WebGL Renderer will now default to pathOpen = true. This fixes issues under WebGL where, for example, adding an arc and calling strokePath, without first calling beginPath will no longer cause rendering artefacts when WebGL tries to close the path with a single tri.
  • Graphics.strokeRoundedRect now issues moveTo commands as part of the drawing sequence, preventing issues under WebGL where on older Android devices it would project additional vertices into the display. Fix #3955 (thanks @alexeymolchan)
  • Creating a Bitmap Mask from a texture atlas that was then used to mask another Game Object also using that same texture atlas would throw the error GL_INVALID_OPERATION : glDrawArrays: Source and destination textures of the draw are the same.. It now renders as expected. Fix #4675 (thanks @JacobCaron)
  • When using the same asset for a Game Object to be used as a mask, it would make other Game Objects using the same asset, that appeared above the mask in the display list, to not render. Fix #4767 (thanks @smjnab)
  • When taking a snapshot in WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in the WebGLSnapshot function. Fix #4956 (thanks @gammafp @telinc1)
  • Particles.EmitterOp.setMethods will now reset both onEmit and onUpdate to their default values. This allows you to reconfigure an emitter op with a new type of value and not have it stuck on the previous one. Fix #3663 (thanks @samme)
  • Particles.EmitterOp now cleanly separates between the different types of property configuration options. start | end will now ease between the two values, min | max will pick a random value between them and random: [] will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)
  • When setting both transparent: true and backgroundColor in the Game Config, it would ignore the transparency and use the color anyway. If transparent, the game is now fully transparent. Fix #5362 (thanks @Hoshinokoe)
  • The Ellipse Game Object now will update the width, height, and geometric position in the setSize method (thanks @PhaserEditor2D)
  • When measuring the last word in a line in a Text Game Object, it no longer adds extra white space to the end (thanks @rexrainbow)
  • Utils.Array.Remove would return an incorrect array of removed elements if one of the items to be removed was skipped in the array. Fix #5398 (thanks @year221)
  • Geom.Intersects.TriangleToLine wouldn't return true if the start or end of the Line fell inside the Triangle, only if the entire Line did. It now checks the start and end points correctly. (thanks @wiserim)
  • Using a Bitmap Mask and a Blend Mode in WebGL would reset the blend mode when the mask was rendered, causing the Game Object to have no blend mode. Fix #5409 (thanks @jcyuan)
  • BitmapMask would become corrupted when resizing the Phaser Game, either via the Scale Manager or directly, because the framebuffer and texture it used for rendering was still at the old dimensions. The BitmapMask now listens for the Renderer RESIZE event and re-creates itself accordingly. Fix #5399 (thanks @Patapits)

Misc Changes

Loader Cache Changes

When loading any of the file types listed below it will no longer store the data file in the cache. For example, when loading a Texture Atlas using a JSON File, it used to store the parsed image data in the Texture Manager and also store the JSON in the JSON Cache under the same key. This has changed in 3.50. The data files are no longer cached, as they are not required by the textures once parsing is completed, which happens during load. This helps free-up memory. How much depends on the size of your data files. And also allows you to easily remove textures based on just their key, without also having to clear out the corresponding data cache.

  • AtlasJSONFile no longer stores the JSON in the JSON Cache once the texture has been created.
  • AtlasXMLFile no longer stores the XML in the XML Cache once the texture has been created.
  • UnityAtlasFile no longer stores the Text in the Text Cache once the texture has been created.
  • BitmapFontFile no longer stores the XML in the XML Cache once the texture has been created.
  • You can now use TextureManager.remove to remove a texture and not have to worry about clearing the corresponding JSON or XML cache entry as well in order to reload a new texture using the same key. Fix #5323 (thanks @TedGriggs)

Lights 2D Updates

The Light Game Object has been rewritten so it now extends the Geom.Circle object, as they shared lots of the same properties and methods anyway. This has cut down on duplicate code massively.

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

Removal of 'resolution' property from across the API

For legacy reasons, Phaser 3 has never properly supported HighDPI devices. It will render happily to them of course, but wouldn't let you set a 'resolution' for the Canvas beyond 1. Earlier versions of 3.x had a resolution property in the Game Config, but it was never fully implemented (for example, it would break zooming cameras). When the Scale Manager was introduced in v3.16 we forced the resolution to be 1 to avoid it breaking anything else internally.

For a long time, the 'resolution' property has been present - taunting developers and confusing new comers. In this release we have finally gone through and removed all references to it. The Game Config option is now gone, it's removed from the Scale Manager, Base Camera and everywhere else where it matters. As much as we would have liked to implement the feature, we've spent too long without it, and things have been built around the assumption it isn't present. The API just wouldn't cope with having it shoe-horned in at this stage. As frustrating as this is, it's even more annoying to just leave the property there confusing people and wasting CPU cycles. Phaser 4 has been built with HighDPI screens in mind from the very start, but it's too late for v3. The following changes are a result of this removal:

  • The Phaser.Scale.Events#RESIZE event no longer sends the resolution as a parameter.
  • The BaseCamera.resolution property has been removed.
  • The internal private BaseCamera._cx, _cy, _cw and _ch properties has been removed, use x, y, width and height instead.
  • The BaseCamera.preRender method no longer receives or uses the resolution parameter.
  • The Camera.preRender method no longer receives or uses the resolution parameter.
  • The CameraManager.onResize method no longer receives or uses the resolution parameter.
  • The Core.Config.resolution property has been removed.
  • The TextStyle.resolution property is no longer read from the Game Config. You can still set it via the Text Style config to a value other than 1, but it will default to this now.
  • The CanvasRenderer no longer reads or uses the Game Config resolution property.
  • The PipelineManager.resize method along with WebGLPipeline.resize and anything else that extends them no longer receives or uses the resolution parameter.
  • The WebGLRenderer.resize and onResize methods no longer receives or uses the resolution parameter.
  • The ScaleManager.resolution property has been removed and all internal use of it.

Removal of 'interpolationPercentage' parameter from across the API

Since v3.0.0 the Game Object render functions have received a parameter called interpolationPercentage that was never used. The renderers do not calculate this value and no Game Objects apply it, so for the sake of clairty, reducing code and removing complexity from the API it has been removed from every single function that either sent or expected the parameter. This touches every single Game Object and changes the parameter order as a result, so please be aware of this if you have your own custom Game Objects, or plugins, that implement their own render methods. In terms of surface API changes, you shouldn't notice anything at all from this removal.

Namespace Updates

  • The Phaser.Curves.MoveTo function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.DOM.GetInnerHeight function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Bob class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsManager class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsPlugin class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Particles.EmitterOp class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.GetTextSize function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.MeasureText function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.TextStyle function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Input.CreatePixelPerfectHandler function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapCirc function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapRect function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Tilemap namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Components namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.MatterGameObject class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.PointerConstraint class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetPhysicsPlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetScenePlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Structs.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Tilemaps.Parsers.Tiled function has now been exposed on the Phaser namespace (thanks @samme)
  • Every single Tilemap.Component function has now been made public. This means you can call the Component functions directly, should you need to, outside of the Tilemap system.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360 @volkans80 @jaabberwocky @maikthomas @atursams @LearningCode2023 @DylanC @BenjaminDRichards @rexrainbow @Riderrr @spwilson2 @EmilSV @PhaserEditor2D @Gangryong @vinerz @trynx @usufruct99 @pirateksh @justin-calleja @monteiz

3.50 Beta Testing Help

A special mention to the following who submitted feedback on the 3.50 Beta releases:

@gammafp Acorn @BlunT76 @PhaserEditor2D @samme @rexrainbow @vforsh @kainage @ccaleb @spayton @FloodGames @buzzjeux @jcyuan @MadDogMayCry0 @Patapits @MMontalto @SBCGames @juanitogan @Racoonacoon @EmilSV @telinc1 @d7561985 @RollinSafary

Sorry if I forgot you!

- JavaScript
Published by photonstorm over 5 years ago

phaser - Phaser v3.50.1

Version 3.50.1 - Subaru - 21st December 2020

  • The new Web Audio Panning feature breaks WebAudio on Safari (OSX and iOS). The stero panner node is now only created if supported. Fix #5460 (thanks @d4rkforce)

Version 3.50.0 - Subaru - 16th December 2020

Due to the massive amount of changes in 3.50 this Change Log is, by its nature, very long. It's important to scan through it, especially if you're porting a game from an earlier version of Phaser to 3.50. However, if you're after more top-level descriptions of what's new, with example code, then please see the posts we will be making to the Phaser site and Phaser Patreon in the coming months after release. We have also updated the Phaser 3 Examples site, so that every single example up there has been rewritten for 3.50, so you don't have to struggle working through old or deprecated syntax. Virtually all new features are covered in new examples, as well.

With that said, we've tried to organize the Change Log into commonly themed sections to make it more digestible, but we appreciate there is a lot here. Please don't feel overwhelmed! If you need clarification about something, join us on the Phaser Discord and feel free to ask.

WebGL Pipelines and Post Processing

WebGL Pipelines are responsible for the rendering of all Game Objects in Phaser and they have had a complete rewrite in 3.50. This was to allow for the introduction of post processing pipelines, now readily available to be created from the new Post FX Pipeline class. The changes in this area have been extensive, so if you use custom WebGL Pipelines in your game already, you must update your code to use Phaser 3.50.

Pipeline Manager

The WebGL.PipelineManager is a new class that is responsible for managing all of the WebGL Pipelines in Phaser. An instance of the Pipeline Manager is created by the WebGL Renderer and is available under the pipelines property. This means that the WebGL Renderer no longer handles pipelines directly, causing the following API changes:

  • WebGLRenderer.pipelines is no longer a plain object containing pipeline instances. It's now an instance of the PipelineManager class. This instance is created during the init and boot phase of the renderer.
  • The WebGLRenderer.currentPipeline property no longer exists, instead use PipelineManager.current.
  • The WebGLRenderer.previousPipeline property no longer exists, instead use PipelineManager.previous.
  • The WebGLRenderer.hasPipeline method no longer exists, instead use PipelineManager.has.
  • The WebGLRenderer.getPipeline method no longer exists, instead use PipelineManager.get.
  • The WebGLRenderer.removePipeline method no longer exists, instead use PipelineManager.remove.
  • The WebGLRenderer.addPipeline method no longer exists, instead use PipelineManager.add.
  • The WebGLRenderer.setPipeline method no longer exists, instead use PipelineManager.set.
  • The WebGLRenderer.rebindPipeline method no longer exists, instead use PipelineManager.rebind.
  • The WebGLRenderer.clearPipeline method no longer exists, instead use PipelineManager.clear.

The Pipeline Manager also offers the following new features:

  • The PipelineManager.resize method automatically handles resize events across all pipelines.
  • The PipelineManager.preRender method calls the pre-render method of all pipelines.
  • The PipelineManager.render method calls the render method of all pipelines.
  • The PipelineManager.postRender method calls the post-render method of all pipelines.
  • The PipelineManager.setMulti method automatically binds the Multi Texture Pipeline, Phasers default.
  • The PipelineManager.clear method will clear the pipeline, store it in previous and free the renderer.
  • The PipelineManager.rebind method will reset the rendering context and restore the previous pipeline, if set.
  • The PipelineManager.copyFrame method will copy a source Render Target to the target Render Target, optionally setting the brightness of the copy.
  • The PipelineManager.blitFrame method will copy a source Render Target to the target Render Target. Unlike copyFrame no resizing takes place and you can optionally set the brightness and erase mode of the copy.
  • The PipelineManager.copyFrameRect method binds the source Render Target and then copies a section of it to the target using gl.copyTexSubImage2D rather than a shader, making it much faster if you don't need blending or preserving alpha details.
  • The PipelineManager.copyToGame method pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws the source Render Target to it. Use when you need to render the final result to the game canvas.
  • The PipelineManager.drawFrame method will copy a source Render Target, optionally to a target Render Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy.
  • The PipelineManager.blendFrames method 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 PipelineManager.blendFramesAdditive method 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 PipelineManager.clearFrame method clears the given Render Target.

New constants have been created to help you reference a pipeline without needing to use strings:

  • Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE for the Bitmap Mask Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE for the Light 2D Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE for the Single Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE for the Multi Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE for the Rope Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINE for the Point Light Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINE for the Post FX Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINE for the Utility Pipeline.

All Game Objects have been updated to use the new constants and Pipeline Manager.

Post FX Pipeline

The Post FX Pipeline is a brand new and special kind of pipeline specifically for handling post processing effects in Phaser 3.50.

Where-as a standard Pipeline allows you to control the process of rendering Game Objects by configuring the shaders and attributes used to draw them, a Post FX Pipeline is designed to allow you to apply processing after the Game Object/s have been rendered.

Typical examples of post processing effects are bloom filters, blurs, light effects and color manipulation.

The pipeline works by creating a tiny vertex buffer with just one single hard-coded quad in it. Game Objects can have a Post Pipeline set on them, which becomes their own unique pipeline instance. Those objects are then rendered using their standard pipeline, but are redirected to the Render Targets owned by the post pipeline, which can then apply their own shaders and effects, before passing them back to the main renderer.

The following properties and methods are available in the new PostFXPipeline class:

  • The PostFXPipeline.gameObject property is a reference to the Game Object that owns the Post Pipeline, if any.
  • The PostFXPipeline.colorMatrix property is a Color Matrix instance used by the draw shader.
  • The PostFXPipeline.fullFrame1 property is a reference to the fullFrame1 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.fullFrame2 property is a reference to the fullFrame2 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.halfFrame1 property is a reference to the halfFrame1 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.halfFrame2 property is a reference to the halfFrame2 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.copyFrame method will copy a source Render Target to the target Render Target, optionally setting the brightness of the copy.
  • The PostFXPipeline.blitFrame method will copy a source Render Target to the target Render Target. Unlike copyFrame no resizing takes place and you can optionally set the brightness and erase mode of the copy.
  • The PostFXPipeline.copyFrameRect method binds the source Render Target and then copies a section of it to the target using gl.copyTexSubImage2D rather than a shader, making it much faster if you don't need blending or preserving alpha details.
  • The PostFXPipeline.copyToGame method pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws the source Render Target to it. Use when you need to render the final result to the game canvas.
  • The PostFXPipeline.drawFrame method will copy a source Render Target, optionally to a target Render Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy.
  • The PostFXPipeline.blendFrames method 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 PostFXPipeline.blendFramesAdditive method 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 PostFXPipeline.clearFrame method clears the given Render Target.
  • The PostFXPipeline.bindAndDraw method binds this pipeline and draws the source Render Target to the target Render Target. This is typically the final step taken in when post processing.

Renamed WebGL Pipelines

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

There is also the new GraphicsPipeline. Previously, the TextureTintPipeline was responsible for rendering all Sprites, Graphics, and Shape objects. Now, it only renders Sprites. All Graphics and Shapes are handled by the new GraphicsPipeline, which uses its own shaders. See below for details about this change.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

WebGL Pipelines Updates

Further pipeline changes are as follows:

  • None of the shaders or pipelines use the uViewMatrix and uModelMatrix uniforms any longer. These were always just plain identity matrices, so there is no point spending CPU and GPU time to set them as uniforms or use them in the shaders. Should you need these uniforms, you can add them to your own custom pipelines.
  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.
  • The WebGLPipeline.shouldFlush method now accepts an optional parameter amount. If given, it will return true if the amount to be added to the vertex count exceeds the vertex capacity. The Multi Pipeline has been updated to now use this method instead of performing the comparison multiple times itself.
  • The RopePipeline now extends MultiPipeline and just changes the topology, vastly reducing the file size.
  • The WebGLPipeline.flushLocked property has been removed. A pipeline can never flush in the middle of a flush anyway, so it was just wasting CPU cycles being set.
  • WebGLPipeline.manager is a new property that is a reference to the WebGL Pipeline Manager.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLPipeline.forceZero is a new boolean property that sets if the pipeline should force the use of texture zero.
  • WebGLPipeline.hasBooted is a new boolean property that is set once the pipeline has finished setting itself up and has booted.
  • WebGLPipeline.isPostFX is a new boolean property that is only set by Post FX Pipelines to help identify them.
  • WebGLPipeline.renderTargets is a new property that holds an array of WebGL Render Targets belonging to the pipeline.
  • WebGLPipeline.currentRenderTarget is a new property that holds a reference to the currently bound Render Target.
  • WebGLPipeline.shaders is a new property that holds an array of all WebGLShader instances that belong to the pipeline.
  • WebGLPipeline.currentShader is a new property that holds a reference to the currently active shader within the pipeline.
  • WebGLPipeline.config is a new property that holds the pipeline configuration object used to create it.
  • WebGLPipeline.projectionMatrix is a new property that holds a Matrix4 used as the projection matrix for the pipeline.
  • WebGLPipeline.setProjectionMatrix is a new method that allows you to set the ortho projection matrix of the pipeline.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLPipeline.setShader is a new method that allows you to set the currently active shader within the pipeline.
  • WebGLPipeline.getShaderByName is a new method that allows you to get a shader from the pipeline based on its name.
  • WebGLPipeline.setShadersFromConfig is a new method that destroys all current shaders and creates brand new ones parsed from the given config object. This is part of the pipeline boot process, but also exposed should you need to call it directly.
  • WebGLPipeline.setGameObject is a new method that custom pipelines can use in order to perform pre-batch tasks for the given Game Object.
  • WebGLPipeline.setVertexBuffer is a new method that checks if the pipelines vertex buffer is active, or not, and if not, binds it as the active buffer. This used to be performed by the WebGL Renderer, but pipelines now manage this directly.
  • WebGLPipeline.preBatch is a new method that is called when a new quad is about to be added to the batch. This is used by Post FX Pipelines to set frame buffers.
  • WebGLPipeline.postBatch is a new method that is called after a quad has been added to the batch. This is used by Post FX Pipelines to apply post processing.
  • WebGLPipeline.unbind is a new method that unbinds the current Render Target, if one is set.
  • WebGLPipeline.batchVert is a new method that adds a single vertex to the vertex buffer and increments the count by 1.
  • WebGLPipeline.batchQuad is a new method that adds a single quad (6 vertices) to the vertex buffer and increments the count, flushing first if adding the quad would exceed the batch limit.
  • WebGLPipeline.batchTri is a new method that adds a single tri (3 vertices) to the vertex buffer and increments the count, flushing first if adding the tri would exceed the batch limit.
  • WebGLPipeline.drawFillRect is a new method that pushes a filled rectangle into the vertex batch.
  • WebGLPipeline.setTexture2D is a new method that sets the texture to be bound to the next available texture unit.
  • WebGLPipeline.bindTexture is a new method that immediately activates the given WebGL Texture and binds it to the requested slot.
  • WebGLPipeline.bindRenderTarget is a new method that binds the given Render Target to a given texture slot.
  • WebGLPipeline.setTime is a new method that gets the current game loop duration to the given shader uniform.

Pipeline Hooks

The WebGLPipeline class has lots of new hooks you can use. These are all empty by default so you can safely override them in your own classes to take advantage of them:

  • WebGLPipeline.onBoot is a new hook you can override in your own pipelines that is called when the pipeline has booted.
  • WebGLPipeline.onResize is a new hook you can override in your own pipelines that is called when the pipeline is resized.
  • WebGLPipeline.onDraw is a new hook you can override in your own pipelines that is called by Post FX Pipelines every time postBatch is invoked.
  • WebGLPipeline.onActive is a new hook you can override in your own pipelines that is called every time the Pipeline Manager makes the pipeline the active pipeline.
  • WebGLPipeline.onBind is a new hook you can override in your own pipelines that is called every time a Game Object asks the Pipeline Manager to use this pipeline, even if it's already active.
  • WebGLPipeline.onRebind is a new hook you can override in your own pipelines that is called every time the Pipeline Manager needs to reset and rebind the current pipeline.
  • WebGLPipeline.onBatch is a new hook you can override in your own pipelines that is called after a new quad (or tri) has been added to the batch.
  • WebGLPipeline.onPreBatch is a new hook you can override in your own pipelines that is called before a new Game Object is about to process itself through the batch.
  • WebGLPipeline.onPostBatch is a new hook you can override in your own pipelines that is called after a new Game Object has added itself to the batch.
  • WebGLPipeline.onPreRender is a new hook you can override in your own pipelines that is called once, per frame, right before anything has been rendered.
  • WebGLPipeline.onRender is a new hook you can override in your own pipelines that is called once, per frame, by every Camera in the Scene that wants to render, at the start of the render process.
  • WebGLPipeline.onPostRender is a new hook you can override in your own pipelines that is called once, per frame, after all rendering has happened and snapshots have been taken.
  • WebGLPipeline.onBeforeFlush is a new hook you can override in your own pipelines that is called immediately before the gl.bufferData and gl.drawArrays calls are made, so you can perform any final pre-render modifications.
  • WebGLPipeline.onAfterFlush is a new hook you can override in your own pipelines that is called after gl.drawArrays, so you can perform additional post-render effects.

Pipeline Events

The WebGLPipeline class now extends the Event Emitter and emits the following new events:

  • The WebGL.Pipelines.Events.AFTER_FLUSH event is dispatched by a WebGL Pipeline right after it has issued a drawArrays command.
  • The WebGL.Pipelines.Events.BEFORE_FLUSH event is dispatched by a WebGL Pipeline right before it is about to flush.
  • The WebGL.Pipelines.Events.BIND event is dispatched by a WebGL Pipeline when it is bound by the Pipeline Manager.
  • The WebGL.Pipelines.Events.BOOT event is dispatched by a WebGL Pipeline when it has finished booting.
  • The WebGL.Pipelines.Events.DESTROY event is dispatched by a WebGL Pipeline when it begins its destruction process.
  • The WebGL.Pipelines.Events.REBIND event is dispatched by a WebGL Pipeline when the Pipeline Manager resets and rebinds it.
  • The WebGL.Pipelines.Events.RESIZE event is dispatched by a WebGL Pipeline when it is resized, usually as a result of the Renderer.

Pipeline Uniform Changes

WebGLShaders have a uniforms object that is automatically populated when the shader is created. It scans all of the active uniforms from the compiled shader and then builds an object containing their WebGLUniformLocation and a value cache.

This saves redundant gl operations for both looking-up uniform locations and setting their values if they're already the currently set values by using the local cache instead.

The WebGLPipeline classes offer a means to set uniform values on the shader (or shaders) belonging to the pipeline. Previously, calling a method such as setFloat3 on a pipeline would pass that call over to WebGLRenderer. The renderer would first check to see if the pipeline program was current, and if not, make it so, before then looking up the uniform location and finally setting it. This is a lot of steps to take for pipelines that potentially need to change uniforms for every Game Object they render.

Under the new methods, and using the new pre-cached uniform locations and values, these extra steps are skipped. The uniform value is set directly, no shader binding takes place and no location look-up happens. This dramatically reduces the number of WebGL ops being issued per frame. To clearly differentiate these pipeline methods, we have renamed them. The new method names are as follows:

  • WebGLPipeline.set1f will set a 1f uniform based on the given name.
  • WebGLPipeline.set2f will set a 2f uniform based on the given name.
  • WebGLPipeline.set3f will set a 3f uniform based on the given name.
  • WebGLPipeline.set4f will set a 4f uniform based on the given name.
  • WebGLPipeline.set1fv will set a 1fv uniform based on the given name.
  • WebGLPipeline.set2fv will set a 2fv uniform based on the given name.
  • WebGLPipeline.set3fv will set a 3fv uniform based on the given name.
  • WebGLPipeline.set4fv will set a 4fv uniform based on the given name.
  • WebGLPipeline.set1iv will set a 1iv uniform based on the given name.
  • WebGLPipeline.set2iv will set a 2iv uniform based on the given name.
  • WebGLPipeline.set3iv will set a 3iv uniform based on the given name.
  • WebGLPipeline.set4iv will set a 4iv uniform based on the given name.
  • WebGLPipeline.set1i will set a 1i uniform based on the given name.
  • WebGLPipeline.set2i will set a 2i uniform based on the given name.
  • WebGLPipeline.set3i will set a 3i uniform based on the given name.
  • WebGLPipeline.set4i will set a 4i uniform based on the given name.
  • WebGLPipeline.setMatrix2fv will set a matrix 2fv uniform based on the given name.
  • WebGLPipeline.setMatrix3fv will set a matrix 3fv uniform based on the given name.
  • WebGLPipeline.setMatrix4fv will set a matrix 4fv uniform based on the given name.

If your code uses any of the old method names, please update them using the list below:

  • WebGLPipeline.setFloat1 has been removed. Please use set1f instead.
  • WebGLPipeline.setFloat2 has been removed. Please use set2f instead.
  • WebGLPipeline.setFloat3 has been removed. Please use set3f instead.
  • WebGLPipeline.setFloat4 has been removed. Please use set4f instead.
  • WebGLPipeline.setFloat1v has been removed. Please use set1fv instead.
  • WebGLPipeline.setFloat2v has been removed. Please use set2fv instead.
  • WebGLPipeline.setFloat3v has been removed. Please use set3fv instead.
  • WebGLPipeline.setFloat4v has been removed. Please use set4fv instead.
  • WebGLPipeline.setInt1 has been removed. Please use set1i instead.
  • WebGLPipeline.setInt2 has been removed. Please use set2i instead.
  • WebGLPipeline.setInt3 has been removed. Please use set3i instead.
  • WebGLPipeline.setInt4 has been removed. Please use set4i instead.
  • WebGLPipeline.setMatrix1 has been removed. Please use setMatrix2fv instead.
  • WebGLPipeline.setMatrix2 has been removed. Please use setMatrix3fv instead.
  • WebGLPipeline.setMatrix3 has been removed. Please use setMatrix4fv instead.

Game Object Pipeline Component Updates

To support the new Post Pipelines in 3.50, the Pipeline Component which most Game Objects inherit has been updated. That means the following new properties and methods are available on all Game Objects that have this component, such as Sprite, Layer, Rope, etc.

  • hasPostPipeline is a new boolean property that indicates if the Game Object has one, or more post pipelines set.
  • postPipelines is a new property that contains an array of Post Pipelines owned by the Game Object.
  • pipelineData is a new object object to store pipeline specific data in.
  • The setPipeline method has been updated with 2 new parameters: pipelineData and copyData. These allow you to populate the pipeline data object during setting.
  • You can now pass a pipeline instance to the setPipeline method, as well as a string.
  • setPostPipeline is a new method that allows you to set one, or more, Post FX Pipelines on the Game Object. And optionally set the pipeline data with them.
  • setPipelineData is a new method that allows you to set a key/value pair into the pipeline data object in a chainable way.
  • getPostPipeline is a new method that will return a Post Pipeline instance from the Game Object based on the given string, function or instance.
  • The resetPipeline method has two new parameters resetPostPipeline and resetData, both false by default, that will reset the Post Pipelines and pipeline data accordingly.
  • resetPostPipeline is a new method that will specifically reset just the Post Pipelines, and optionally the pipeline data.
  • removePostPipeline is a new method that will destroy and remove the given Post Pipeline from the Game Object.

Utility Pipeline

The Utility Pipeline is a brand new default special-use WebGL Pipeline that is created by and belongs to the Pipeline Manager.

It provides 4 shaders and handy associated methods:

1) Copy Shader. A fast texture to texture copy shader with optional brightness setting. 2) Additive Blend Mode Shader. Blends two textures using an additive blend mode. 3) Linear Blend Mode Shader. Blends two textures using a linear blend mode. 4) Color Matrix Copy Shader. Draws a texture to a target using a Color Matrix.

You do not extend this pipeline, but instead get a reference to it from the Pipeline Manager via the setUtility method. You can also access its methods, such as copyFrame, directly from both the Pipeline Manager and from Post FX Pipelines, where its features are most useful.

This pipeline provides methods for manipulating framebuffer backed textures, such as copying or blending one texture to another, copying a portion of a texture, additively blending two textures, flipping textures and more. All essential and common operations for post processing.

The following properties and methods are available in the new UtilityPipeline class:

  • The UtilityPipeline.colorMatrix property is an instance of a ColorMatrix class, used by the draw shader.
  • The UtilityPipeline.copyShader property is a reference to the Copy Shader.
  • The UtilityPipeline.addShader property is a reference to the additive blend shader.
  • The UtilityPipeline.linearShader property is a reference to the linear blend shader.
  • The UtilityPipeline.colorMatrixShader property is a reference to the color matrix (draw) shader.
  • The UtilityPipeline.fullFrame1 property is a full sized Render Target that can be used as a temporary buffer during post processing calls.
  • The UtilityPipeline.fullFrame2 property is a full sized Render Target that can be used as a temporary buffer during post processing calls.
  • The UtilityPipeline.halfFrame1 property is a half sized Render Target that can be used as a temporary buffer during post processing calls, where a small texture is required for more intensive operations.
  • The UtilityPipeline.halfFrame2 property is a half sized Render Target that can be used as a temporary buffer during post processing calls, where a small texture is required for more intensive operations.
  • The UtilityPipeline.copyFrame method will copy a source Render Target to the target Render Target, optionally setting the brightness of the copy.
  • The UtilityPipeline.blitFrame method will copy a source Render Target to the target Render Target. Unlike copyFrame no resizing takes place and you can optionally set the brightness and erase mode of the copy.
  • The UtilityPipeline.copyFrameRect method binds the source Render Target and then copies a section of it to the target using gl.copyTexSubImage2D rather than a shader, making it much faster if you don't need blending or preserving alpha details.
  • The UtilityPipeline.copyToGame method pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws the source Render Target to it. Use when you need to render the final result to the game canvas.
  • The UtilityPipeline.drawFrame method will copy a source Render Target, optionally to a target Render Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy.
  • The UtilityPipeline.blendFrames method 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 UtilityPipeline.blendFramesAdditive method 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 UtilityPipeline.clearFrame method clears the given Render Target.
  • The UtilityPipeline.setUVs method allows you to set the UV values for the 6 vertices that make-up the quad belonging to the Utility Pipeline.
  • The UtilityPipeline.setTargetUVs method sets the vertex UV coordinates of the quad used by the shaders so that they correctly adjust the texture coordinates for a blit frame effect.
  • The UtilityPipeline.flipX method horizontally flips the UV coordinates of the quad used by the shaders.
  • The UtilityPipeline.flipY method vertically flips the UV coordinates of the quad used by the shaders.
  • The UtilityPipeline.resetUVs method resets the quad vertice UV values to their default settings.

Light Pipeline Update

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh Game Objects now support rendering with normal maps.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Point Lights Pipeline

The Point Light Pipeline is a brand new pipeline in 3.50 that was creates specifically for rendering the new Point Light Game Objects in WebGL.

It extends the WebGLPipeline and sets the required shader attributes and uniforms for Point Light rendering.

You typically don't access or set the pipeline directly, but rather create instances of the Point Light Game Object instead. However, it does have the following unique methods:

  • The PointLightPipeline.batchPointLight method is a special-case method that is called directly by the Point Light Game Object during rendering and allows it to add itself into the rendering batch.
  • The PointLightPipeline.batchLightVert method is a special internal method, used by batchPointLight that adds a single Point Light vert into the batch.

Graphics Pipeline and Graphics Game Object Changes

The Graphics Pipeline is a new pipeline added in 3.50 that is responsible for rendering Graphics Game Objects and all of the Shape Game Objects, such as Arc, Rectangle, Star, etc. Due to the new pipeline some changes have been made:

  • The Graphics Pipeline now uses much simpler vertex and fragment shaders with just two attributes (inPosition and inColor), making the vertex size and memory-use 57% smaller.
  • The private _tempMatrix1, 2, 3 and 4 properties have all been removed from the pipeline.
  • A new public calcMatrix property has been added, which Shape Game Objects use to maintain transform state during rendering.
  • The Graphics Pipeline no longer makes use of tintEffect or any textures.
  • Because Graphics and Shapes now render with their own pipeline, you are able to exclude the pipeline and those Game Objects entirely from custom builds, further reducing the final bundle size.

As a result of these changes the following features are no longer available:

  • Graphics.setTexture has been removed. You can no longer use a texture as a 'fill' for a Graphic. It never worked with any shape other than a Rectangle, anyway, due to UV mapping issues, so is much better handled via the new Mesh Game Object.
  • Graphics._tempMatrix1, 2 and 3 have been removed. They're not required internally any longer.
  • Graphics.renderWebGL now uses the standard GetCalcMatrix function, cutting down on duplicate code significantly.

Single Pipeline Update

There is a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGLShader

WebGLShader is a new class that is created and belongs to WebGL Pipeline classes. When the pipeline is created it will create a WebGLShader instance for each one of its shaders, as defined in the pipeline configuration.

This class encapsulates everything needed to manage a shader in a pipeline, including the shader attributes and uniforms, as well as lots of handy methods such as set2f, for setting uniform values on this shader. Uniform values are automatically cached to avoid unnecessary gl operations.

Typically, you do not create an instance of this class directly, as it works in unison with the pipeline to which it belongs. You can gain access to this class via a pipeline's shaders array, post-creation.

The following properties and methods are available in the new WebGLShader class:

  • The WebGLShader.pipeline property is a reference to the WebGL Pipeline that owns the WebGLShader instance.
  • The WebGLShader.name property is the name of the shader.
  • The WebGLShader.renderer property is a reference to the WebGL Renderer.
  • The WebGLShader.gl property is a reference to the WebGL Rendering Context.
  • The WebGLShader.program property is the WebGL Program created from the vertex and fragment shaders.
  • The WebGLShader.attributes property is an array of objects that describe the vertex attributes of the shader.
  • The WebGLShader.vertexComponentCount property is the total amount of vertex attribute components of 32-bit length.
  • The WebGLShader.vertexSize property is the size, in bytes, of a single vertex.
  • The WebGLShader.uniforms property is an object that is automatically populated with all active uniforms in the shader.
  • The WebGLShader.createAttributes method takes the vertex attributes config and parses it, creating the shader attributes. This is called automatically.
  • The WebGLShader.bind method sets the program the shader uses as being active. Called automatically when the parent pipeline needs this shader.
  • The WebGLShader.rebind method sets the program the shader uses as being active and resets all of the vertex attribute pointers.
  • The WebGLShader.setAttribPointers method sets the vertex attribute pointers. Called automatically during bind.
  • The WebGLShader.createUniforms method populates the uniforms object with details about all active uniforms.
  • The WebGLShader.hasUniform method returns a boolean if the given uniform exists.
  • The WebGLShader.resetUniform method resets the cached value for the given uniform.
  • The WebGLShader.setUniform1 method is an internal method used for setting a single value uniform on the shader.
  • The WebGLShader.setUniform2 method is an internal method used for setting a double value uniform on the shader.
  • The WebGLShader.setUniform3 method is an internal method used for setting a triple value uniform on the shader.
  • The WebGLShader.setUniform4 method is an internal method used for setting a quadruple value uniform on the shader.
  • The WebGLShader.set1f method sets a 1f uniform based on the given name.
  • The WebGLShader.set2f method sets a 2f uniform based on the given name.
  • The WebGLShader.set3f method sets a 3f uniform based on the given name.
  • The WebGLShader.set4f method sets a 4f uniform based on the given name.
  • The WebGLShader.set1fv method sets a 1fv uniform based on the given name.
  • The WebGLShader.set2fv method sets a 2fv uniform based on the given name.
  • The WebGLShader.set3fv method sets a 3fv uniform based on the given name.
  • The WebGLShader.set4fv method sets a 4fv uniform based on the given name.
  • The WebGLShader.set1iv method sets a 1iv uniform based on the given name.
  • The WebGLShader.set2iv method sets a 2iv uniform based on the given name.
  • The WebGLShader.set3iv method sets a 3iv uniform based on the given name.
  • The WebGLShader.set4iv method sets a 4iv uniform based on the given name.
  • The WebGLShader.set1i method sets a 1i uniform based on the given name.
  • The WebGLShader.set2i method sets a 2i uniform based on the given name.
  • The WebGLShader.set3i method sets a 3i uniform based on the given name.
  • The WebGLShader.set4i method sets a 4i uniform based on the given name.
  • The WebGLShader.setMatrix2fv method sets a matrix 2fv uniform based on the given name.
  • The WebGLShader.setMatrix3fv method sets a matrix 3fv uniform based on the given name.
  • The WebGLShader.setMatrix4fv method sets a matrix 4fv uniform based on the given name.
  • The WebGLShader.destroy method removes all external references and deletes the program and attributes.

Render Target

RenderTarget is a brand new class that encapsulates a WebGL framebuffer and the WebGL Texture that displays it. Instances of this class are typically created by, and belong to WebGL Pipelines, however other Game Objects and classes can take advantage of Render Targets as well.

The following properties and methods are available in the new RenderTexture class:

  • The RenderTarget.renderer property is a reference to the WebGL Renderer.
  • The RenderTarget.framebuffer property is the WebGLFramebuffer belonging to the Render Target.
  • The RenderTarget.texture property is a WebGLTexture belonging to the Render Target and bound to the framebuffer.
  • The RenderTarget.width property is the width of the Render Target.
  • The RenderTarget.height property is the height of the Render Target.
  • The RenderTarget.scale property is the scale of the Render Target, applied to the dimensions during resize.
  • The RenderTarget.minFilter property is the min filter of the texture.
  • The RenderTarget.autoClear property is a boolean that controls if the Render Target is automatically cleared when bound.
  • The RenderTarget.autoResize property is a boolean that controls if the Render Target is automatically resized if the WebGLRenderer resizes.
  • The RenderTarget.setAutoResize method lets you set the auto resize of the Render Target.
  • The RenderTarget.resize method lets you resize the Render Target.
  • The RenderTarget.bind method sets the Render Target as being the active fbo in the renderer and optionally clears and adjusts the viewport.
  • The RenderTarget.adjustViewport method sets the viewport to match the Render Target dimensions.
  • The RenderTarget.clear method disables the scissors, clears the Render Target and resets the scissors again.
  • The RenderTarget.unbind method flushes the renderer and pops the Render Target framebuffer from the stack.
  • The RenderTarget.destroy method removes all external references and deletes the framebuffer and texture.

WebGL Renderer

New WebGL Multi-Texture Support

The Multi Pipeline (previously called the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw-call bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.
  • The WebGL.Utils.getComponentCount function has been removed as this is no longer required internally.

WebGLRenderer New Features, Updates and API Changes

  • WebGLRenderer.instancedArraysExtension is a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.
  • WebGLRenderer.vaoExtension is a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.
  • WebGLRenderer.resetProgram is a new method that will rebind the current program, without flushing or changing any properties.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • WebGLRenderer.finalType is a new boolean property that signifies if the current Game Object being rendered is the final one in the list.
  • The WebGLRenderer.updateCanvasTexture method will now set gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL to true, which should stop issues where you update a Text Game Object, having added a Render Texture or Spine Game Object to the Scene after it, which switches the PMA setting. Fix #5064 #5155 (thanks @hugoruscitti @immangrove-supertree)
  • WebGLRenderer.previousPipeline is a new property that is set during a call to clearPipeline and used during calls to rebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.
  • The WebGLRenderer.rebindPipeline method has been changed slightly. Previously, you had to specify the pipelineInstance, but this is now optional. If you don't, it will use the new previousPipeline property instead. If not set, or none given, it will now return without throwing gl errors as well.
  • WebGLRenderer.defaultScissor is a new property that holds the default scissor dimensions for the renderer. This is modified during resize and avoids continuous array generation in the preRender loop.
  • The WebGLRenderer.nativeTextures array has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in the TextureSource objects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy.
  • The WebGLRenderer.deleteTexture method has a new optional boolean parameter reset which allows you to control if the WebGLRenderer.resetTextures method is called, or not, after the texture is deleted.
  • The WebGLRenderer.getMaxTextures method has been removed. This is no longer needed as you can use the WebGLRenderer.maxTextures property instead.
  • The WebGLRenderer.setProgram method now returns a boolean. true if the program was set, otherwise false.
  • WebGLRenderer.setFloat1 has been removed. Use WebGLPipeline.set1f or WebGLShader.set1f instead.
  • WebGLRenderer.setFloat2 has been removed. Use WebGLPipeline.set2f or WebGLShader.set2f instead.
  • WebGLRenderer.setFloat3 has been removed. Use WebGLPipeline.set3f or WebGLShader.set3f instead.
  • WebGLRenderer.setFloat4 has been removed. Use WebGLPipeline.set4f or WebGLShader.set4f instead.
  • WebGLRenderer.setFloat1v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set1fv instead.
  • WebGLRenderer.setFloat2v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set2fv instead.
  • WebGLRenderer.setFloat3v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set3fv instead.
  • WebGLRenderer.setFloat4v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set4fv instead.
  • WebGLRenderer.setInt1 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set1i instead.
  • WebGLRenderer.setInt2 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set2i instead.
  • WebGLRenderer.setInt3 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set3i instead.
  • WebGLRenderer.setInt4 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set4i instead.
  • WebGLRenderer.setMatrix2 has been removed. Use WebGLPipeline.setMatrix2fv or WebGLShader.setMatrix2fv instead.
  • WebGLRenderer.setMatrix3 has been removed. Use WebGLPipeline.setMatrix3fv or WebGLShader.setMatrix3fv instead.
  • WebGLRenderer.setMatrix4 has been removed. Use WebGLPipeline.setMatrix4fv or WebGLShader.setMatrix4fv instead.
  • The WebGLRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.
  • WebGLRenderer.fboStack is a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.
  • WebGLRenderer.pushFramebuffer is a new method that is used to push a framebuffer onto the fbo stack before setting it as the current framebuffer. This should now be called in place of setFramebuffer. Remember to call popFramebuffer after using it.
  • WebGLRenderer.popFramebuffer is a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.
  • WebGLRenderer.setFramebuffer has a new optional boolean parameter resetTextures which will reset the WebGL Textures, if set to true (which is the default).
  • WebGLRenderer.isBooted is a new boolean property that lets you know if the renderer has fully finished booting.
  • The WebGLRenderer now extends the Event Emitter, allowing you to listen to renderer specific events.
  • WebGLRenderer.defaultCamera has been removed as it's not used anywhere internally any longer.
  • The WebGLRenderer.setVertexBuffer method has been removed along with the WebGLRenderer.currentVertexBuffer property. This is now set directly by the WebGL Pipeline, as needed.
  • The WebGLRenderer.setIndexBuffer method has been removed along with the WebGLRenderer.currentIndexBuffer property. This is now set directly by the WebGL Pipeline, as needed.
  • WebGLRenderer.resetScissor is a new method that will reset the gl scissor state to be the current scissor, if there is one, without modifying the stack.
  • WebGLRenderer.resetViewport is a new method that will reset the gl viewport to the current renderer dimensions.
  • WebGLRenderer.renderTarget is a new property that contains a Render Target that is bound to the renderer and kept resized to match it.
  • WebGLRenderer.beginCapture is a new method that will bind the renderers Render Target, so everything drawn is redirected to it.
  • WebGLRenderer.endCapture is a new method that will unbind the renderers Render Target and return it, preventing anything else from being drawn to it.
  • WebGLRenderer.setProjectionMatrix is a new method that sets the global renderer projection matrix to the given dimensions.
  • WebGLRenderer.resetProjectionMatrix is a new method that resets the renderer projection matrix back to match the renderer size.
  • WebGLRenderer.getAspectRatio is a new method that returns the aspect ratio of the renderer.

WebGL ModelViewProjection Removed

The ModelViewProjection object contained a lot of functions that Phaser never used internally. Instead, the functions available in them were already available in the Math.Matrix4 class. So the pipelines have been updated to use a Matrix4 instead and all of the MVP functions have been removed. The full list of removed functions is below:

  • projIdentity has been removed.
  • projPersp has been removed.
  • modelRotateX has been removed.
  • modelRotateY has been removed.
  • modelRotateZ has been removed.
  • viewLoad has been removed.
  • viewRotateX has been removed.
  • viewRotateY has been removed.
  • viewRotateZ has been removed.
  • viewScale has been removed.
  • viewTranslate has been removed.
  • modelIdentity has been removed.
  • modelScale has been removed.
  • modelTranslate has been removed.
  • viewIdentity has been removed.
  • viewLoad2D has been removed.
  • projOrtho has been removed.

WebGL and Canvas Renderer Events

  • Phaser.Renderer.Events is a new namespace for events emitted by the Canvas and WebGL Renderers.
  • Renderer.Events.PRE_RENDER is a new event dispatched by the Phaser Renderer. This happens right at the start of the render process.
  • Renderer.Events.RENDER is a new event dispatched by the Phaser Renderer. This happens once for every camera, in every Scene at the start of its render process.
  • Renderer.Events.POST_RENDER is a new event dispatched by the Phaser Renderer. This happens right at the end of the render process.
  • Renderer.Events.RESIZE is a new event dispatched by the Phaser Renderer whenever it is resized.

Canvas Renderer Updates

  • CanvasRenderer.isBooted is a new boolean property that lets you know if the renderer has fully finished booting.
  • The CanvasRenderer now extends the Event Emitter, allowing you to listen to renderer specific events.

Camera - New Features, Updates and API Changes

The Camera API has changed in line with the new pipeline updates. To this end, the following changes have taken place:

The Camera class now inherits the Pipeline Component. This gives it new features, in line with the other pipelines changes in 3.50, such as Camera.setPipeline, Camera.setPostPipeline, Camera.setPipelineData and so on. This is a much more powerful and flexible way of setting camera effects, rather than it managing its own framebuffer and texture directly.

To that end, the following properties and methods have been removed to tidy things up:

  • The Camera.renderToTexture property has been removed. Effects are now handled via pipelines.
  • The Camera.renderToGame property has been removed. Effects are now handled via pipelines.
  • The Camera.canvas property has been removed. Textures are handled by pipelines.
  • The Camera.context property has been removed. Textures are handled by pipelines.
  • The Camera.glTexture property has been removed. GL Textures are handled by pipelines.
  • The Camera.framebuffer property has been removed. GL Framebuffers are handled by pipelines.
  • The Camera.setRenderToTexture method has been removed. Effects are now handled via pipelines.
  • The Camera.clearRenderToTexture method has been removed. Effects are now handled via pipelines.

These changes mean that you can no longer render a Camera to a canvas in Canvas games.

Other changes and fixes:

  • Camera.zoomX is a new property that allows you to specifically set the horizontal zoom factor of a Camera.
  • Camera.zoomY is a new property that allows you to specifically set the vertical zoom factor of a Camera.
  • The Camera.setZoom method now allows you to pass two parameters: x and y, to control the zoomX and zoomY values accordingly.
  • The Camera.zoom property now returns an average of the zoomX and zoomY properties.
  • Cameras.Scene2D.Events.FOLLOW_UPDATE is a new Event that is dispatched by a Camera when it is following a Game Object. It is dispatched every frame, right after the final Camera position and internal matrices have been updated. Use it if you need to react to a camera, using its most current position and the camera is following something. Fix #5253 (thanks @rexrainbow)
  • If the Camera has roundPixels set it will now round the internal scroll factors and worldView during the preRender step. Fix #4464 (thanks @Antriel)

Spine Plugin - New Features, API Changes and Bug Fixes

  • The Spine Runtimes have been updated to 3.8.99, which are the most recent non-beta versions. Please note, you will need to re-export your animations if you're working in a version of Spine lower than 3.8.20. We do not impose this requirement, the Spine editor does.
  • SpineContainer is a new Game Object available via this.add.spineContainer to which you can add Spine Game Objects only. It uses a special rendering function to retain batching, even across multiple container or Spine Game Object instances, resulting in dramatically improved performance compared to using regular Containers. You can still use regular Containers if you need, but they do not benefit from the new batching.
  • A Spine Game Object with setVisible(false) will no longer still cause internal gl commands and is now properly skipped, retaining any current batch in the process. Fix #5174 (thanks @Kitsee)
  • The Spine Game Object WebGL Renderer will no longer clear the type if invisible and will only end the batch if the next type doesn't match.
  • The Spine Game Object WebGL Renderer will no longer rebind the pipeline if it was the final object on the display list, saving lots of gl commands.
  • The Webpack build scripts have all been updated for Webpack 4.44.x. Fix #5243 (thanks @RollinSafary)
  • There is a new npm script npm run plugin.spine.runtimes which will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo into plugins/spine/ in order for this to work and then run npm i.
  • Spine Game Objects can now be rendered to Render Textures. Fix #5184 (thanks @Kitsee)
  • Using > 128 Spine objects in a Container would cause a WebGL: INVALID_OPERATION: vertexAttribPointer: no ARRAY_BUFFER is bound and offset is non-zero error if you added any subsequent Spine objects to the Scene. There is now no limit. Fix #5246 (thanks @d7561985)
  • The Spine Plugin will now work in HEADLESS mode without crashing. Fix #4988 (thanks @raimon-segura)
  • Spine Game Objects now use -1 as their default blend mode, which means 'skip setting it', as blend modes should be handled by the Spine skeletons directly.
  • The Spine TypeScript defs have been updated for the latest version of the plugin and to add SpineContainers.
  • The SpineGameObject.setAnimation method will now use the trackIndex parameter if ignoreIfPlaying is set and run the check against this track index. Fix #4842 (thanks @vinerz)
  • The SpineFile will no longer throw a warning if adding a texture into the Texture Manager that already exists. This allows you to have multiple Spine JSON use the same texture file, however, it also means you now get no warning if you accidentally load a texture that exists, so be careful with your keys! Fix #4947 (thanks @Nomy1)
  • The Spine Plugin destroy method will now no longer remove the Game Objects from the Game Object Factory, or dispose of the Scene Renderer. This means when a Scene is destroyed, it will keep the Game Objects in the factory for other Scenes to use. Fix #5279 (thanks @Racoonacoon)
  • SpinePlugin.gameDestroy is a new method that is called if the Game instance emits a destroy event. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.
  • SpineFile will now check to see if another identical atlas in the load queue is already loading the texture it needs and will no longer get locked waiting for a file that will never complete. This allows multiple skeleton JSONs to use the same atlas data. Fix #5331 (thanks @Racoonacoon)
  • SpineFile now uses a ! character to split the keys, instead of an underscore, preventing the plugin from incorrectly working out the keys for filenames with underscores in them. Fix #5336 (thanks @Racoonacoon)
  • SpineGameObject.willRender is no longer hard-coded to return true. It instead now takes a Camera parameter and performs all of the checks needed before returning. Previously, this happened during the render functions.
  • The Spine Plugin now uses a single instance of the Scene Renderer when running under WebGL. All instances of the plugin (installed per Scene) share the same base Scene Renderer, avoiding duplicate allocations and resizing events under multi-Scene games. Fix #5286 (thanks @spayton BunBunBun)

Game Objects - New Features, API Changes and Bug Fixes

Lots of the core Phaser Game Objects have been improved in 3.50 and there are several new Game Objects as well.

Render Texture Game Object

The Render Texture Game Object has been rewritten to use the new RenderTarget class internally, rather than managing its own framebuffer and gl textures directly. The core draw methods are now a lot simpler and no longer require manipulating render pipelines.

As a result of these changes the following updates have happened:

  • RenderTexture.renderTarget is a new property that contains a RenderTarget instance, which is used for all drawing.
  • The RenderTexture.framebuffer property has been removed. You can now access this via RenderTexture.renderTarget.framebuffer.
  • The RenderTexture.glTexture property has been removed. You can now access this via RenderTexture.renderTarget.texture.
  • The RenderTexture.gl property has been removed.

Render Textures have the following new features:

  • RenderTexture.beginDraw is a new method that allows you to create a batched draw to the Render Texture. Use this method to begin the batch.
  • RenderTexture.batchDraw is a new method that allows you to batch the drawing of an object to the Render Texture. You should never call this method unless you have previously started a batch with beginDraw. You can call this method as many times as you like, to draw as many objects as you like, without causing a framebuffer bind.
  • RenderTexture.batchDrawFrame is a new method that allows you to batch the drawing of a texture frame to the Render Texture. You should never call this method unless you have previously started a batch with beginDraw. You can call this method as many times as you like, to draw as many frames as you like, without causing a framebuffer bind.
  • RenderTexture.endDraw is a new method that ends a previously created batched draw on the Render Texture. Use it to write all of your batch changes to the Render Texture.
  • You can now draw a Group to a RenderTexture. Previously, it failed to pass the camera across, resulting in none of the Group children being drawn. Fix #5330 (thanks @somnolik)

Render Textures have the following bug fixes:

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • RenderTexture.erase has never worked when using the Canvas Renderer and a texture frame, only with Game Objects. It now works with both. Fix #5422 (thanks @vforsh)

Point Lights Game Object

The Point Light Game Object is brand new in 3.50 and 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 radial 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 calculations. 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 display 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 PointLight Game Object has the following unique properties and methods:

  • The PointLight.color property is an instance of the Color object that controls the color value of the light.
  • The PointLight.intensity property sets the intensity of the light. The colors of the light are multiplied by this value during rendering.
  • The PointLight.attenuation property sets the attenuation of the light, which is the force with which the light falls off from its center.
  • The PointLight.radius property sets the radius of the light, in pixels. This value is also used for culling.

Point Lights also have corresponding Factory and Creator functions, available from within a Scene:

js this.add.pointlight(x, y, color, radius, intensity, attenuation);

and

js this.make.pointlight({ x, y, color, radius, intensity, attenuation });

Mesh Game Object

The Mesh Game Object has been rewritten from scratch in v3.50 with a lot of changes to make it much more useful. It is accompanied by the new Geom.Mesh set of functions.

  • Geom.Mesh is a new namespace that contains the Mesh related geometry functions. These are stand-alone functions that you may, or may not require, depending on your game.
  • Geom.Mesh.Vertex is a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.
  • Geom.Mesh.Face is a new class that consists of references to the three Vertex instances that construct a single Face in a Mesh and provides methods for manipulating them.
  • Geom.Mesh.GenerateVerts is a new function that will return an array of Vertex and Face objects generated from the given data. You can provide index, or non-index vertex lists, along with UV data, normals, colors and alpha which it will parse and return the results from.
  • Geom.Mesh.GenerateGridVerts is a new function that will generate a series of Vertex objects in a grid format, based on the given GenerateGridConfig config file. You can set the size of the grid, the number of segments to split it into, translate it, color it and tile the texture across it. The resulting data can be easily used by a Mesh Game Object.
  • Geom.Mesh.GenerateObjVerts is a new function that will generate a series of Vertex objects based on the given parsed Wavefront Obj Model data. You can optionally scale and translate the generated vertices and add them to a Mesh.
  • Geom.Mesh.ParseObj is a new function that will parse a triangulated Wavefront OBJ file into model data into a format that the GenerateObjVerts function can consume.
  • Geom.Mesh.ParseObjMaterial is a new function that will parse a Wavefront material file and extract the diffuse color data from it, combining it with the parsed object data.
  • Geom.Mesh.RotateFace is a new function that will rotate a Face by a given amount, based on an optional center of rotation.
  • Loader.OBJFile is a new File Loader type that can load triangulated Wavefront OBJ files, and optionally material files, which are then parsed and stored in the OBJ Cache.
  • The Mesh constructor and MeshFactory signatures have changed to scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first. indicies is a new parameter that allows you to provide indexed vertex data to create the Mesh from, where the indicies array holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. The indicies array is optional. If your data is not indexed, then simply pass null or an empty array for this parameter.
  • The Mesh Game Object now has the Animation State Component. This allows you to create and play animations across the texture of a Mesh, something that previously wasn't possible. As a result, the Mesh now adds itself to the Update List when added to a Scene.
  • Mesh.addVertices is a new method that allows you to add vertices to a Mesh Game Object based on the given parameters. This allows you to modify a mesh post-creation, or populate it with data at a later stage.
  • Mesh.addVerticesFromObj is a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the new OBJFile with a this.load.obj call, then you can use the key with this method. This method also takes an optional scale and position parameters to control placement of the created model within the Mesh.
  • Mesh.hideCCW is a new boolean property that, when enabled, tells a Face to not render if it isn't counter-clockwise. You can use this to hide backward facing Faces.
  • Mesh.modelPosition is a new Vector3 property that allows you to translate the position of all vertices in the Mesh.
  • Mesh.modelRotation is a new Vector3 property that allows you to rotate all vertices in the Mesh.
  • Mesh.modelScale is a new Vector3 property that allows you to scale all vertices in the Mesh.
  • Mesh.panX is a new function that will translate the view position of the Mesh on the x axis.
  • Mesh.panY is a new function that will translate the view position of the Mesh on the y axis.
  • Mesh.panZ is a new function that will translate the view position of the Mesh on the z axis.
  • Mesh.setPerspective is a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.
  • Mesh.setOrtho is a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.
  • Mesh.clear is a new method that will destroy all Faces and Vertices and clear the Mesh.
  • Mesh.depthSort is a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.
  • Mesh.addVertex is a new method that allows you to add a new single Vertex into the Mesh.
  • Mesh.addFace is a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.
  • Mesh.getFaceCount new is a new method that will return the total number of Faces in the Mesh.
  • Mesh.getVertexCount new is a new method that will return the total number of Vertices in the Mesh.
  • Mesh.getFace new is a new method that will return a Face instance from the Mesh based on the given index.
  • Mesh.getFaceAt new is a new method that will return an array of Face instances from the Mesh based on the given position. The position is checked against each Face, translated through the optional Camera and Mesh matrix. If more than one Face intersects, they will all be returned but the array will be depth sorted first, so the first element will be that closest to the camera.
  • Mesh.vertices is now an array of GameObject.Vertex instances, not a Float32Array.
  • Mesh.faces is a new array of GameObject.Face instances, which is populated during a call to methods like addVertices or addModel.
  • Mesh.totalRendered is a new property that holds the total number of Faces that were rendered in the previous frame.
  • Mesh.setDebug is a new method that allows you to render a debug visualization of the Mesh vertices to a Graphics Game Object. You can provide your own Graphics instance and optionally callback that is invoked during rendering. This allows you to easily visualize the vertices of your Mesh to help debug UV mapping.
  • The Mesh now renders by iterating through the Faces array, not the vertices. This allows you to use Array methods such as BringToTop to reposition a Face, thus changing the drawing order without having to repopulate all of the vertices. Or, for a 3D model, you can now depth sort the Faces.
  • The Mesh Game Object now extends the SingleAlpha component and the alpha value is factored into the final alpha value per vertex during rendering. This means you can now set the whole alpha across the Mesh using the standard setAlpha methods. But, if you wish to, you can still control the alpha on a per-vertex basis as well.
  • The Mesh renderer will now check to see if the pipeline capacity has been exceeded for every Face added, allowing you to use Meshes with vertex counts that exceed the pipeline capacity without causing runtime errors.
  • You can now supply just a single numerical value as the colors parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the color for all vertices created.
  • You can now supply just a single numerical value as the alphas parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the alpha for all vertices created.
  • Mesh.debugGraphic is a new property that holds the debug Graphics instance reference.
  • Mesh.debugCallback is a new property that holds the debug render callback.
  • Mesh.renderDebugVerts is a new method that acts as the default render callback for setDebug if none is provided.
  • Mesh.preDestroy is a new method that will clean-up the Mesh arrays and debug references on destruction.
  • Mesh.isDirty is a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically in preUpdate to avoid generating lots of math when nothing has changed.
  • The Mesh.uv array has been removed. All UV data is now bound in the Vertex instances.
  • The Mesh.colors array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.alphas array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.tintFill property is now a boolean and defaults to false.

Layer Game Object

A Layer is a special type of Game Object that acts as a Display List. You can add any type of Game Object to a Layer, just as you would to a Scene. Layers can be used to visually group together 'layers' of Game Objects:

```javascript const spaceman = this.add.sprite(150, 300, 'spaceman'); const bunny = this.add.sprite(400, 300, 'bunny'); const elephant = this.add.sprite(650, 300, 'elephant');

const layer = this.add.layer();

layer.add([ spaceman, bunny, elephant ]); ```

The 3 sprites in the example above will now be managed by the Layer they were added to. Therefore, if you then set layer.setVisible(false) they would all vanish from the display.

You can also control the depth of the Game Objects within the Layer. For example, calling the setDepth method of a child of a Layer will allow you to adjust the depth of that child within the Layer itself, rather than the whole Scene. The Layer, too, can have its depth set as well.

The Layer class also offers many different methods for manipulating the list, such as the methods moveUp, moveDown, sendToBack, bringToTop and so on. These allow you to change the display list position of the Layers children, causing it to adjust the order in which they are rendered. Using setDepth on a child allows you to override this.

Layers can have Post FX Pipelines set, which allows you to easily enable a post pipeline across a whole range of children, which, depending on the effect, can often be far more efficient that doing so on a per-child basis.

Layers have no position or size within the Scene. This means you cannot enable a Layer for physics or input, or change the position, rotation or scale of a Layer. They also have no scroll factor, texture, tint, origin, crop or bounds.

If you need those kind of features then you should use a Container instead. Containers can be added to Layers, but Layers cannot be added to Containers.

However, you can set the Alpha, Blend Mode, Depth, Mask and Visible state of a Layer. These settings will impact all children being rendered by the Layer.

BitmapText Game Object

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has to work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.
  • You can now use setMaxWidth on DynamicBitmapText, which wasn't previously possible. Fix #4997 (thanks @AndreaBoeAbrahamsen)

Quad Game Object Removed

The Quad Game Object has been removed from v3.50.0.

You can now create your own Quads easily using the new Geom.Mesh.GenerateGridVerts function, which is far more flexible than the old quads were.

Animation API - New Features, API Changes and Bug Fixes

If you use Animations in your game, please read the following important API changes in 3.50:

The Animation API has had a significant overhaul to improve playback handling. Instead of just playing an animation based on its global key, you can now supply a new PlayAnimationConfig object instead, which allows you to override any of the default animation settings, such as duration, delay and yoyo (see below for the full list). This means you no longer have to create lots of duplicate animations just to change properties such as duration, and can now set them dynamically at run-time as well.

  • The Animation class no longer extends EventEmitter, as it no longer emits any events directly. This means you cannot now listen for events directly from an Animation instance. All of the events are now dispatched by the Game Objects instead.
  • All of the SPRITE_ANIMATION_KEY events have been removed. Instead, please use the new events which all carry the frameKey parameter, which can be used to handle frame specific events. The only exception to this is ANIMATION_COMPLETE_KEY, which is a key specific version of the completion event.
  • ANIMATION_UPDATE_EVENT is a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.
  • ANIMATION_STOP_EVENT is a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of the stop methods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)
  • The Game Object Component.Animation component has been renamed to AnimationState and has moved namespace. It's now in Phaser.Animations instead of GameObjects.Components to help differentiate it from the Animation class when browsing the documentation.
  • The play, playReverse, playAfterDelay, playAfterRepeat and chain Sprite and Animation Component methods can now all take a Phaser.Types.Animations.PlayAnimationConfig configuration object, as well as a string, as the key parameter. This allows you to override any default animation setting with those defined in the config, giving you far greater control over animations on a Game Object level, without needing to globally duplicate them.
  • AnimationState.create is a new method that allows you to create animations directly on a Sprite. These are not global and never enter the Animation Manager, instead residing within the Sprite itself. This allows you to use the same keys across both local and global animations and set-up Sprite specific local animations.
  • AnimationState.generateFrameNumbers is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • AnimationState.generateFrameNames is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • All playback methods: play, playReverse, playAfterDelay and playAfterRepeat will now check to see if the given animation key exists locally on the Sprite first. If it does, it's used, otherwise it then checks the global Animation Manager for the key instead.
  • AnimationState.skipMissedFrames is now used when playing an animation, allowing you to create animations that run at frame rates far exceeding the refresh rate, or that will update to the correct frame should the game lag. Feature #4232 (thanks @colorcube)
  • AnimationManager.addMix is a new method that allows you to create mixes 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.
  • AnimationManager.getMix is a new method that will return the mix duration between the two given animations.
  • AnimationManager.removeMix is a new method that will remove the mixture between either two animations, or all mixtures for the given animation.
  • AnimationState.remove is a new method that will remove a locally stored Animation instance from a Sprite.
  • AnimationState.get is a new method that will return a locally stored Animation instance from the Sprite.
  • AnimationState.exists is a new method that will check if a locally stored Animation exists on the Sprite.
  • The internal AnimationState.remove method has been renamed to globalRemove.
  • AnimationState.textureManager is a new property that references the global Texture Manager.
  • AnimationState.anims is a new property that contains locally created Animations in a Custom Map.
  • AnimationState.play and Sprite.play no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • AnimationState.playReverse and Sprite.playReverse no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • The AnimationState.delayedPlay method has been renamed to playAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration.
  • The AnimationState.stopOnRepeat method has been renamed to stopAfterRepeat
  • The AnimationState.getCurrentKey method has been renamed to getName.
  • AnimationState.getFrameName is a new method that will return the key of the current Animation Frame, if an animation has been loaded.
  • AnimationState.playAfterDelay and Sprite.playAfterDelay are new methods that will play the given animation after the delay in ms expires.
  • AnimationState.playAfterRepeat and Sprite.playAfterRepeat are new methods that will play the given animation after the current animation finishes repeating. You can also specify the number of repeats allowed left to run.
  • The AnimationState.chain method is now available on the Sprite class.
  • The AnimationState.stopAfterDelay method is now available on the Sprite class.
  • The AnimationState.stopAfterRepeat method is now available on the Sprite class.
  • The AnimationState.stopOnFrame method is now available on the Sprite class.
  • AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser. Please see the comprehensive documentation for this method for full details on how to do this.
  • AnimationState now handles all of the loading of the animation. It no longer has to make calls out to the Animation Manager or Animation instance itself and will load the animation data directly, replacing as required from the optional PlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.
  • The PlayAnimationConfig.frameRate property lets you optionally override the animation frame rate.
  • The PlayAnimationConfig.duration property lets you optionally override the animation duration.
  • The PlayAnimationConfig.delay property lets you optionally override the animation delay.
  • The PlayAnimationConfig.repeat property lets you optionally override the animation repeat counter.
  • The PlayAnimationConfig.repeatDelay property lets you optionally override the animation repeat delay value.
  • The PlayAnimationConfig.yoyo property lets you optionally override the animation yoyo boolean.
  • The PlayAnimationConfig.showOnStart property lets you optionally override the animation show on start value.
  • The PlayAnimationConfig.hideOnComplete property lets you optionally override the animation hide on complete value.
  • The PlayAnimationConfig.startFrame property lets you optionally set the animation frame to start on.
  • The PlayAnimationConfig.timeScale property lets you optionally set the animation time scale factor.
  • AnimationState.delayCounter is a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animation START events fire. Fix #4426 (thanks @bdaenen)
  • AnimationState.hasStarted is a new boolean property that allows you to tell if the current animation has started playing, or is still waiting for a delay to expire.
  • AnimationState.showOnStart is a new boolean property that controls if the Game Object should have setVisible(true) called on it when the animation starts.
  • AnimationState.hideOnComplete is a new boolean property that controls if the Game Object should have setVisible(false) called on it when the animation completes.
  • The AnimationState.chain method docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does!
  • The AnimationState.setDelay method has been removed. It never actually worked and you can now perform the same thing by calling either playAfterDelay or setting the delay property in the play config.
  • The AnimationState.getDelay method has been removed. You can now read the delay property directly.
  • The AnimationState.setRepeat method has been removed. You can achieve the same thing by setting the repeat property in the play config, or adjusting the public repeatCounter property if the animation has started.
  • AnimationState.handleStart is a new internal private method that handles the animation start process.
  • AnimationState.handleRepeat is a new internal private method that handles the animation repeat process.
  • AnimationState.handleStop is a new internal private method that handles the animation stop process.
  • AnimationState.handleComplete is a new internal private method that handles the animation complete process.
  • AnimationState.emitEvents is a new internal private method that emits animation events, cutting down on duplicate code.
  • The AnimationState.restart method has a new optional boolean parameter resetRepeats which controls if you want to reset the repeat counter during the restart, or not.
  • Animation.getTotalFrames is a new method that will return the total number of frames in the animation. You can access it via this.anims.currentAnim.getTotalFrames from a Sprite.
  • Animation.calculateDuration is a new method that calculates the duration, frameRate and msPerFrame for a given animation target.
  • The BuildGameObjectAnimation function now uses the PlayAnimationConfig object to set the values.
  • Sprite.playReverse is a new method that allows you to play the given animation in reverse on the Sprite.
  • Sprite.playAfterDelay is a new method that allows you to play the given animation on the Sprite after a delay.
  • Sprite.stop is a new method that allows you to stop the current animation on the Sprite.
  • AnimationManager.load has been removed as it's no longer required.
  • AnimationManager.staggerPlay has been fixed so you can now pass in negative stagger values.
  • AnimationManager.staggerPlay has a new optional boolean parameter staggerFirst, which allows you to either include or exclude the first child in the stagger calculations.
  • The Animation.completeAnimation method has been removed as it's no longer required.
  • The Animation.load method has been removed as it's no longer required.
  • The Animation.setFrame method has been removed as it's no longer required.
  • The Animation.getFirstTick method has no longer needs the includeDelay parameter, as it's handled by AnimationState now.
  • The Animation.getFrames method has a new optional boolean parameter sortFrames which will run a numeric sort on the frame names after constructing them, if a string-based frame is given.
  • Types.Animations.Animation has a new boolean property sortFrames, which lets Phaser numerically sort the generated frames.
  • AnimationState.timeScale is a new public property that replaces the old private _timeScale property.
  • AnimationState.delay is a new public property that replaces the old private _delay property.
  • AnimationState.repeat is a new public property that replaces the old private _repeat property.
  • AnimationState.repeatDelay is a new public property that replaces the old private _repeatDelay property.
  • AnimationState.yoyo is a new public property that replaces the old private _yoyo property.
  • AnimationState.inReverse is a new public property that replaces the old private _reverse property.
  • AnimationState.startAnimation is a new public method that replaces the old private _startAnimation method.
  • The AnimationState.getProgress method has been fixed so it will return correctly if the animation is playing in reverse.
  • The AnimationState.globalRemove method will now always be called when an animation is removed from the global Animation Manager, not just once.
  • The AnimationState.getRepeat method has now been removed. You can get the value from the repeat property.
  • The AnimationState.setRepeatDelay method has now been removed. You can set the value using the repeatDelay config property, or changing it at run-time.
  • AnimationState.complete is a new method that handles the completion in animation playback.
  • The AnimationState.setTimeScale method has now been removed. You can set the value using the timeScale config property, or changing it at run-time.
  • The AnimationState.getTimeScale method has now been removed. You can read the value using the timeScale property.
  • The AnimationState.getTotalFrames method has been fixed and won't error if called when no animation is loaded.
  • The AnimationState.setYoyo method has now been removed. You can set the value using the yoyo config property, or changing it at run-time.
  • The AnimationState.getYoyo method has now been removed. You can read the value using the yoyo property.
  • The AnimationState.stopAfterRepeat method now has an optional parameter repeatCount, so you can tell the animation to stop after a specified number of repeats, not just 1.
  • When playing an animation in reverse, if it reached the first frame and had to repeat, it would then jump to the frame before the final frame and carry on, skipping out the final frame.
  • The AnimationState.updateFrame method has now been removed. Everything is handled by setCurrentFrame instead, which removes one extra step out of the update process.
  • GenerateFrameNames will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers would include the __BASE frame by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.
  • GenerateFrameNumbers can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.
  • GenerateFrameNames can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.

Tilemap - New Features, API Changes and Bug Fixes

There are three large changes to Tilemaps in 3.50. If you use tilemaps, you must read this section:

1) The first change is that there are no longer DynamicTilemapLayer and StaticTilemapLayer classes. They have both been removed and replaced with the new TilemapLayer class. This new class consolidates features from both and provides a lot cleaner API experience, as well as speeding up internal logic.

In your game where you use map.createDynamicLayer or map.createStaticLayer replace it with map.createLayer instead.

2) The second change is that the Tilemap system now supports isometric, hexagonal and staggered isometric map types, along with the previous orthogonal format, thanks to a PR from @svipal. You can now export maps using any of these orientations from the Tiled Map Editor and load them into Phaser using the existing tilemap loading API. No further changes need to take place in the way your maps are loaded.

3) The Tilemap.createFromObjects method has been overhauled to make it much more useful. The method signature has changed and it now takes a new CreateFromObjectLayerConfig configuration object, or an array of them, which allows much more fine-grained control over which objects in the Tiled Object Layers are converted and what they are converted to. Previously it could only convert to Sprites, but you can now pass in a custom class, filter based on id, gid or name, even provide a Container to add the created Game Objects to. Please see the new documentation for this method and the config object for more details. Fix #3817 #4613 (thanks @georgzoeller @Secretmapper)

  • The Tilemap.createDynamicLayer method has been renamed to createLayer.
  • The Tilemap.createStaticLayer method has been removed. Use createLayer instead.
  • The Tilemap.createBlankDynamicLayer method has been renamed to createBlankLayer.
  • The Tilemap.convertLayerToStatic method has been removed as it is no longer required.
  • The TilemapLayerWebGLRenderer function will no longer iterate through the layer tilesets, drawing tiles from only that set. Instead all it does now is iterate directly through only the tiles. This allows it to take advantage of the new Multi Texturing pipeline and also draw multi-tileset isometric layers correctly.
  • Phaser.Types.Tilemaps.TilemapOrientationType is a new type def that holds the 4 types of map orientation now supported.
  • The Tile.updatePixelXY method now updates the tile XY position based on map type.
  • ParseTilesets will now correctly handle non-consecutive tile IDs. It also now correctly sets the maxId property, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)
  • Tilemap.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • LayerData.orientation is a new property that holds the tilemap layers orientation constant.
  • LayerData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • MapData.orientation is a new property that holds the tilemap layers orientation constant.
  • MapData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • Tilemaps.Components.HexagonalWorldToTileY is a new function that converts a world Y coordinate to hexagonal tile Y coordinate.
  • Tilemaps.Components.StaggeredWorldToTileY is a new function that converts a world Y coordinate to staggered tile Y coordinate.
  • Tilemaps.Components.HexagonalWorldToTileXY is a new function that converts world coordinates to hexagonal tile coordinates.
  • Tilemaps.Components.IsometricWorldToTileXY is a new function that converts world coordinates to isometric tile coordinates.
  • Tilemaps.Components.StaggeredWorldToTileXY is a new function that converts world coordinates to staggered tile coordinates.
  • Tilemaps.Components.HexagonalTileToWorldY is a new function that converts a hexagonal Y coordinate to a world coordinate.
  • Tilemaps.Components.StaggeredTileToWorldY is a new function that converts a staggered Y coordinate to a world coordinate.
  • Tilemaps.Components.HexagonalTileToWorldXY is a new function that converts hexagonal tile coordinates to world coordinates.
  • Tilemaps.Components.IsometricTileToWorldXY is a new function that converts isometric tile coordinates to world coordinates.
  • Tilemaps.Components.StaggeredTileToWorldXY is a new function that converts staggered tile coordinates to world coordinates.
  • Tilemaps.Components.GetTileToWorldXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldXXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetCullTilesFunction is a new function that returns the correct culling function to use.
  • Tilemaps.Components.HexagonalCullTiles is a new function that culls tiles in a hexagonal map.
  • Tilemaps.Components.StaggeredCullTiles is a new function that culls tiles in a staggered map.
  • Tilemaps.Components.IsometricCullTiles is a new function that culls tiles in a isometric map.
  • Tilemaps.Components.CullBounds is a new function that calculates the cull bounds for an orthogonal map.
  • Tilemaps.Components.HexagonalCullBounds is a new function that calculates the cull bounds for a hexagonal map.
  • Tilemaps.Components.StaggeredCullBounds is a new function that calculates the cull bounds for a staggered map.
  • Tilemaps.Components.RunCull is a new function that runs the culling process from the combined bounds and tilemap.
  • Tilemap._convert is a new internal private hash of tilemap conversion functions used by the public API.
  • The Tilemap._isStaticCall method has been removed and no Tilemap methods now check this, leading to faster execution.
  • The Arcade Physics Sprites vs. Tilemap Layers flow has changed. Previously, it would iterate through a whole bunch of linked functions, taking lots of jumps in the process. It now just calls the GetTilesWithinWorldXY component directly, saving lots of overhead.
  • The method Tilemap.weightedRandomize has changed so that the parameter weightedIndexes is now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional.
  • The method TilemapLayer.weightedRandomize has changed so that the parameter weightedIndexes is now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional.

Update List - New Features, API Changes and Bug Fixes

The way in which Game Objects add themselves to the Scene Update List has changed. Instead of being added by the Factory methods, they will now add and remove themselves based on the new ADDED_TO_SCENE and REMOVED_FROM_SCENE events. This means, you can now add Sprites directly to a Container, or Group, and they'll animate properly without first having to be part of the Update List. The full set of changes and new features relating to this follow:

  • GameObjects.Events.ADDED_TO_SCENE is a new event, emitted by a Game Object, when it is added to a Scene, or a Container that is part of the Scene.
  • GameObjects.Events.REMOVED_FROM_SCENE is a new event, emitted by a Game Object, when it is removed from a Scene, or a Container that is part of the Scene.
  • Scenes.Events.ADDED_TO_SCENE is a new event, emitted by a Scene, when a new Game Object is added to the display list in the Scene, or a Container that is on the display list.
  • Scenes.Events.REMOVED_FROM_SCENE is a new event, emitted by a Scene, when it a Game Object is removed from the display list in the Scene, or a Container that is on the display list.
  • GameObject.addedToScene is a new method that custom Game Objects can use to perform additional set-up when a Game Object is added to a Scene. For example, Sprite uses this to add itself to the Update List.
  • GameObject.removedFromScene is a new method that custom Game Objects can use to perform additional tear-down when a Game Object is removed from a Scene. For example, Sprite uses this to remove themselves from the Update List.
  • Game Objects no longer automatically remove themselves from the Update List during preDestroy. This should be handled directly in the removedFromScene method now.
  • The Container will now test to see if any Game Object added to it is already on the display list, or not, and emit its ADDED and REMOVED events accordingly. Fix #5267 #3876 (thanks @halgorithm @mbpictures)
  • DisplayList.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • DisplayList.addChildCallback is a new method that overrides the List callback and fires the new ADDED events.
  • DisplayList.removeChildCallback is a new method that overrides the List callback and fires the new REMOVED events.
  • GameObjectCreator.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • GameObjectFactory.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • ProcessQueue.checkQueue is a new boolean property that will make sure only unique objects are added to the Process Queue.
  • The Update List now uses the new checkQueue property to ensure no duplicate objects are on the active list.
  • DOMElementFactory, ExternFactory, ParticleManagerFactor, RopeFactory and SpriteFactory all no longer add the objects to the Update List, this is now handled by the ADDED events instead.
  • Sprite, Rope, ParticleEmitterManager, Extern and DOMElement now all override the addedToScene and removedFromScene callbacks to handle further set-up tasks.

Input Manager and Mouse Manager - New Features, API Changes and Bug Fixes

  • ScaleManager.refresh is now called when the Game.READY event fires. This fixes a bug where the Scale Manager would have the incorrect canvas bounds, because they were calculated before a previous canvas was removed from the DOM. Fix #4862 (thanks @dranitski)
  • The Game Config property inputMouseCapture has been removed, as this is now split into 3 new config options:
  • inputMousePreventDefaultDown is a new config option that allows you to control preventDefault calls specifically on mouse down events. Set it via input.mouse.preventDefaultDown in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultUp is a new config option that allows you to control preventDefault calls specifically on mouse up events. Set it via input.mouse.preventDefaultUp in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultMove is a new config option that allows you to control preventDefault calls specifically on mouse move events. Set it via input.mouse.preventDefaultMove in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultWheel is a new config option that allows you to control preventDefault calls specifically on mouse wheel events. Set it via input.mouse.preventDefaultWheel in the Game Config. It defaults to true, the same as the previous capture property did.
  • The MouseManager.capture property has been removed, as this is now split into 3 new config options (see below)
  • MouseManager.preventDefaultDown is a new boolean property, set via the inputMousePreventDefaultDown config option that allows you to toggle capture of mouse down events at runtime.
  • MouseManager.preventDefaultUp is a new boolean property, set via the inputMousePreventDefaultUp config option that allows you to toggle capture of mouse up events at runtime.
  • MouseManager.preventDefaultMove is a new boolean property, set via the inputMousePreventDefaultMove config option that allows you to toggle capture of mouse move events at runtime.
  • MouseManager.preventDefaultWheel is a new boolean property, set via the inputMousePreventDefaultWheel config option that allows you to toggle capture of mouse wheel at runtime.
  • In the MouseManager the up, down and move events are no longer set as being passive if captured. Over, Out, Wheel and the Window level Down and Up events are always flagged as being passive. Wheel events are non-passive if capturing is enabled.
  • The GamepadPlugin will now call refreshPads as part of its start process. This allows you to use Gamepads across multiple Scenes, without having to wait for a connected event from each one of them. If you've already had a connected event in a previous Scene, you can now just read the pads directly via this.input.gamepad.pad1 and similar. Fix #4890 (thanks @Sytten)
  • Shutting down the Gamepad plugin (such as when sleeping a Scene) no longer calls GamepadPlugin.disconnectAll, but destroying it does.
  • Gamepad._created is a new private internal property that keeps track of when the instance was created. This is compared to the navigator timestamp in the update loop to avoid event spamming. Fix #4890.
  • Pointer.down will now check if the browser is running under macOS and if the ctrl key was also pressed, if so, it will flag the down event as being a right-click instead of a left-click, as per macOS conventions. Fix #4245 (thanks @BigZaphod)
  • When destroying an interactive Game Object that had useHandCursor enabled, it would reset the CSS cursor to default, even if the cursor wasn't over that Game Object. It will now only reset the cursor if it's over the Game Object being destroyed. Fix #5321 (thanks @JstnPwll)
  • The InputPlugin.shutdown method will now reset the CSS cursor, in case it was set by any Game Objects in the Scene that have since been destroyed.
  • The InputPlugin.processOverEvents has had a duplicate internal loop removed from it (thanks KingCosmic)

Tint Component Updates and resulting Shader Changes

Phaser has had the ability to apply an additive tint to a Game Object since the beginning, and gained 'filled tints', with and without texture alpha, in v3.11. While this was handy, it introduced a 3-way if-else condition to the shaders to handle the different modes. Plus, setting tint colors was also generating rgb order Float32 color values for each Game Object, making reading those colors back again difficult (as they'd return in BGR order).

This has all changed in 3.50, as outlined below. Tint values are now used directly in the shader and don't pass through a color conversion function first. Lots of private properties have been removed and the shaders no longer have a 3-way if-else block. All of this means improved performance and a slight reduction in memory overhead.

  • Tint.tintTopLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTL which has now been removed.
  • Tint.tintTopRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTR which has now been removed.
  • Tint.tintBottomLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBL which has now been removed.
  • Tint.tintBottomRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBR which has now been removed.
  • The property Tint._isTinted has been removed as it's no longer required.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they now read the color value as outTint.bgr instead of outTint.rgb. This allows the colors to remain in RGB order within the Tint component.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they no longer have a 3-way check on the outTintEffect value.
  • The Multi Pipeline, Bitmap Text, Render Texture, Text, TileSprite and Camera now all read the tint values from the public properties instead of the private _tintTL etc ones. They also now set the tintEffect value directly from the tintFill property, removing another conditional check.
  • The function GetColorFromValue has been removed as it's no longer used internally.
  • The Rope.tintFill property is now a boolean, not an integer, and can no longer take 2 as a value for a complete fill. Instead, you should provide a solid color texture with no alpha.
  • As a result of the change to the shader, all uses of the WebGL Util function getTintAppendFloatAlphaAndSwap have been replaced with getTintAppendFloatAlpha instead.
  • As a result of the change to the shader, the Multi Pipeline now uses the WebGLRenderer.whiteTexture and tintEffect mode of 1 by default, instead of mode 2 (which has been removed) and a transparent texture. This ensures Graphics and Shapes objects still render correctly under the new smaller shader code.
  • WebGLRenderer.whiteTexture is a new property that is a reference to a pure white 4x4 texture that is created during Boot by the Texture Manager. The Graphics Pipeline uses this internally for all geometry fill rendering.
  • The TextureManager now generates a new texture with the key __WHITE during its boot process. This is a pure white 4x4 texture used by the Graphics pipelines.
  • Config.images.white is a new Game Config property that specifies the 4x4 white PNG texture used by Graphics rendering. You can override this via the config, but only do so if needed.

Arcade Physics - New Features, API Changes and Bug Fixes

Prior to v3.50 an Arcade Physics Body could be one of two states: immovable, or movable. An immovable body could not receive any impact from another Body. If something collided with it, it wouldn't even separate to break free from the collision (the other body had to take the full separation value). It was intended for objects such as platforms, ground or walls, there they absolutely shouldn't move under any circumstances. As a result, two immovable bodies could never be collided together. While this worked for scenery-like items, it didn't work if you required maybe 2 players who could collide with each other, but should never be able to push one another. As of 3.50 all physics bodies now have a new property pushable that allows this. A pushable body can share separation with its collider, as well as take on mass-based velocity from the impact. A non-pushable body will behave differently depending on what it collides with. For example, a pushable body hitting a non-pushable (or immovable) body will rebound off it.

  • The Arcade Physics Body class has a new boolean property pushable (true, by default). This allows you to set if a Body can be physically pushed by another Body, or not. Fix #4175 #4415 (thanks @inmylo @CipSoft-Components)
  • Body.setPushable is a new chainable method that allows you to set the pushable state of a Body.
  • Arcade.Components.Pushable is a new component, inherited by the standard Arcade Physics Image and Sprite classes.
  • Bodies will now check to see if they are blocked in the direction they're being pushed, before resolving the collision. This helps stop some bodies from being pushed into other objects.
  • Bodies will now check which direction they were moving and separate accordingly. This helps stop some bodies from being pushed into other objects.
  • ArcadePhysics.disableUpdate is a new method that will prevent the Arcade Physics World update method from being called when the Scene updates. By disabling it, you're free to call the update method yourself, passing in your own delta and time values.
  • ArcadePhysics.enableUpdate is a new method that will make the Arcade Physics World update in time with the Scene update. This is the default, so only call this if you have specifically disabled it previously.
  • ArcadeWorldConfig.customUpdate is a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. If true the World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)
  • Physics.Arcade.Body.setCollideWorldBounds now has a new optional parameter onWorldBounds which allows you to enable the Body's onWorldBounds property in the same call (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityX is a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityY is a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)
  • The PhysicsGroup config now has two new optional properties maxVelocityX and maxVelocityY which allows you to set the maximum velocity on bodies added to the Group (thanks @samme)
  • The Arcade.Body.resetFlags method has a new optional boolean parameter clear. If set, it clears the wasTouching flags on the Body. This happens automatically when Body.reset is called. Previous to this, the flags were not reset until the next physics step (thanks @samme)
  • Physics.Arcade.ProcessX is a new set of functions, called by the SeparateX function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Physics.Arcade.ProcessY is a new set of functions, called by the SeparateY function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Arcade.Body.center values were incorrect after collisions with the world bounds or (for rectangular bodies) after collisions with another body. The body center is now updated after those separations (thanks @samme)
  • The Arcade Physics WORLD_STEP event now has a new parameter: the delta argument (thanks @samme)
  • The Arcade Body drag property has been redefined when damping is used and scales the damping multiplier by the physics step delta. Drag is now the velocity retained after 1 second instead of after 1 step, when damping is used. This makes damping consistent for different physics step rates and more accurate when fixedStep is off. If you use drag you will need to change any existing drag values to get the same effects as before. Convert drag to drag ^ 60 or drag ^ fps if you use a different step rate (thanks @samme)

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.
  • You can now use this.renderer from within a Scene, as it's now a Scene-level property and part of the Injection Map.
  • Clock.addEvent can now take an existing TimerEvent object, as well as a config object. If a TimerEvent is given it will be removed from the Clock, reset and then added. This allows you to pool TimerEvents rather than constantly create and delete them. Fix #4115 (thanks @jcyuan)
  • Clock.removeEvent is a new method that allows you to remove a TimerEvent, or an array of them, from all internal lists of the current Clock.
  • Group.getMatching is a new method that will return any members of the Group that match the given criteria, such as getMatching('visible', true) (thanks @atursams)
  • Utils.Array.SortByDigits is a new function that takes the given array of strings and runs a numeric sort on it, ignoring any non-digits.
  • GroupCreateConfig, which is used when calling Group.createMultiple or Group.createFromConfig, can now accept the following new properties: setOrigin: { x, y, stepX, stepY } which are applied to the items created by the Group.
  • Transform.copyPosition is a new method that will copy the position from the given object to the Game Object (thanks @samme)
  • The Text.MeasureText function, which is used to calculate the ascent and descent of Text Game Objects whenever the style, or font size, is changed, has been updated to use the new actualBoundingBoxAscent functions present in modern browsers. This allows for significantly faster ascent calculations than previously. Older browsers, such as IE, will still fall back (thanks @rexrainbow)
  • GameObjects.GetCalcMatrix is a new function that is used to calculate the transformed Game Object matrix, based on the given Game Object, Camera and Parent. This function is now used by the following Game Objects: BitmapText (Static and Dynamic), Graphics, Extern, Mesh, Rope, Shader, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. This dramatically reduces the amount of duplicate code across the API.
  • Utils.Array.Matrix.Translate is a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.
  • Vertor3.addScale is a new method that will add the given vector and multiply it in the process.
  • When defining the ease used with a Particle Emitter you can now set easeParams in the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh)
  • BitmapMask.createMask is a new method that will internally create the WebGL textures and framebuffers required for the mask. This is now used by the constructor and if the context is lost. It now also clears any previous textures/fbos that may have been created first, helping prevent memory leaks.
  • BitmapMask.clearMask will delete any WebGL textures or framebuffers the mask is using. This is now called when the mask is destroyed, or a new mask is created upon it.
  • Quaternion now has a new property onChangeCallback which, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.
  • The Quaternion.set method has a new optional boolean parameter update (defaults to true), which will call the onChangeCallback if set.
  • Quaternion.setFromEuler is a new method that will set the quaternion from the given Euler object, optionally calling the onChangeCallback in the process.
  • Quaternion.setFromRotationMatrix is a new method that will set the rotation of the quaternion from the given Matrix4.
  • Vector3.setFromMatrixPosition is a new method that will set the components of the Vector3 based on the position of the given Matrix4.
  • Vector3.setFromMatrixColumn is a new method that will set the components of the Vector3 based on the specified Matrix4 column.
  • Vector3.fromArray is a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.
  • Vector3.min is a new method that will set the components of the Vector3 based on the Main.min between it and the given Vector3.
  • Vector3.max is a new method that will set the components of the Vector3 based on the Main.max between it and the given Vector3.
  • Vector3.addVectors is a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.
  • Vector3.addScalar is a new method that will multiply the components of the Vector3 by the scale value given.
  • Vector3.applyMatrix3 is a new method that will take a Matrix3 and apply it to the Vector3.
  • Vector3.applyMatrix4 is a new method that will take a Matrix4 and apply it to the Vector3.
  • Vector3.projectViewMatrix is a new method that multiplies the Vector3 by the given view and projection matrices.
  • Vector3.unprojectViewMatrix is a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.
  • Matrix4.setValues is a new method that allows you to set all of the matrix components individually. Most internal methods now use this.
  • Matrix.multiplyToMat4 is a new method that multiplies a Matrix4 by the given src Matrix4 and stores the results in the out Matrix4.
  • Matrix4.fromRotationXYTranslation is a new method that takes the rotation and position vectors and builds this Matrix4 from them.
  • Matrix4.getMaxScaleOnAxis is a new method that will return the maximum axis scale from the Matrix4.
  • Matrix4.lookAtRH is a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.
  • Matrix4.transform is a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.
  • Matrix4.multiplyMatrices is a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.
  • Matrix4.premultiply is a new method that takes a Matrix4 and multiplies it by the current Matrix4.
  • Matrix4.getInverse is a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.
  • CameraManager.getVisibleChildren is a new method that is called internally by the CameraManager.render method. It filters the DisplayList, so that Game Objects that pass the willRender test for the given Camera are added to a sub-list, which is then passed to the renderer. This avoids the renderer having to do any checks on the children, it just renders each one in turn.
  • Physics.Arcade.Body.setDamping is a new method that allows you to set the useDamping property of a Body in a chainable way. Fix #5352 (thanks @juanitogan)
  • The GameObjects.Graphics.fillGradientStyle method can now accept a different alpha value for each of the fill colors. The default is still 1. If you only provide a single alpha, it'll be used for all colors. Fix #5044 (thanks @zhangciwu)
  • Types.Core.PipelineConfig is a new configuration object that you can set in the Game Config under the pipeline property. It allows you to define custom WebGL pipelines as part of the Game Config, so they're automatically installed and ready for use by all Scenes in your game. You can either set the pipeline object, or set it under the render sub-config.
  • Utils.Object.DeepCopy is a new function that will recursively deep copy an array of object.
  • Time.TimerEvent.getRemaining is a new method that returns the time interval until the next iteration of the Timer Event (thanks @samme)
  • Time.TimerEvent.getRemainingSeconds is a new method that returns the time interval until the next iteration of the Timer Event in seconds (thanks @samme)
  • Time.TimerEvent.getOverallRemaining is a new method that returns the time interval until the last iteration of the Timer Event (thanks @samme)
  • Time.TimerEvent.getOverallRemainingSeconds is a new method that returns the time interval until the last iteration of the Timer Event in seconds (thanks @samme)
  • GameObjects.Video.loadMediaStream is a new method that allows you to hook a Video Game Object up to a Media Stream, rather than a URL, allowing you to stream video from a source such as a webcam (thanks @pirateksh)
  • Display.Color.ColorSpectrum is a new function that will return an array of 1024 Color Object elements aligned in a Color Spectrum layout, where the darkest colors have been omitted.
  • AsepriteFile is a new File Type for the Loader that allows you to load Aseprite images and animation data for use with the new Aseprite animation features. You can call this via this.load.asesprite(png, json).
  • GameObject.displayList is a new property that contains a reference to the Display List to which the Game Object has been added. This will typically either by the Display List owned by a Scene, or a Layer Game Object. You should treat this property as read-only.
  • The Shader Game Object now supports being able to use a Render Texture as a sampler2D texture on the shader #5423 (thanks @ccaleb)
  • BaseSound.pan, HTMLAudioSound.pan and WebAudioSound.pan are new properties that allow you to get or set the pan value of a sound, a value between -1 (full left pan) and 1 (full right pan). Note that pan only works under Web Audio, but the property and event still exists under HTML5 Audio for compatibility (thanks @pi-kei)
  • WebAudioSound.setPan is a new method that allows you to set the pan of the sound. A value between -1 (full left pan) and 1 (full right pan) (thanks @pi-kei)
  • Sound.Events.PAN is a new event dispatched by both Web Audio and HTML5 Audio Sound objects when their pan changes (thanks @pi-kei)

ColorMatrix

  • Phaser.Display.ColorMatrix is a new class that allows you to create and manipulate a 5x4 color matrix, which can be used by shaders or graphics operations.
  • The ColorMatrix.set method allows you to set the values of a ColorMatrix.
  • The ColorMatrix.reset method will reset the ColorMatrix to its default values.
  • The ColorMatrix.getData method will return the data in the ColorMatrix as a Float32Array, useful for setting in a shader uniform.
  • The ColorMatrix.brightness method lets you set the brightness of the ColorMatrix.
  • The ColorMatrix.saturate method lets you set the saturation of the ColorMatrix.
  • The ColorMatrix.desaturate method lets you desaturate the colors in the ColorMatrix.
  • The ColorMatrix.hue method lets you rotate the hues of the ColorMatrix by the given amount.
  • The ColorMatrix.grayscale method converts the ColorMatrix to grayscale.
  • The ColorMatrix.blackWhite method converts the ColorMatrix to black and whites.
  • The ColorMatrix.contrast method lets you set the contrast of the ColorMatrix.
  • The ColorMatrix.negative method converts the ColorMatrix to negative values.
  • The ColorMatrix.desaturateLuminance method applies a desaturated luminance to the ColorMatrix.
  • The ColorMatrix.sepia method applies a sepia tone to the ColorMatrix.
  • The ColorMatrix.night method applies a night time effect to the ColorMatrix.
  • The ColorMatrix.lsd method applies a trippy color effect to the ColorMatrix.
  • The ColorMatrix.brown method applies a brown tone to the ColorMatrix.
  • The ColorMatrix.vintagePinhole method applies a vintage pinhole color effect to the ColorMatrix.
  • The ColorMatrix.kodachrome method applies a kodachrome color effect to the ColorMatrix.
  • The ColorMatrix.technicolor method applies a technicolor color effect to the ColorMatrix.
  • The ColorMatrix.polaroid method applies a polaroid color effect to the ColorMatrix.
  • The ColorMatrix.shiftToBGR method shifts the values of the ColorMatrix into BGR order.
  • The ColorMatrix.multiply method multiplies two ColorMatrix data sets together.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Earcut has now been exposed and is available via Geom.Polygon.Earcut and is fully documented.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.
  • Pointer.downTime now stores the event timestamp of when the first button on the input device was pressed down, not just when button 1 was pressed down.
  • Pointer.upTime now stores the event timestamp of when the final depressed button on the input device was released, not just when button 1 was released.
  • The Pointer.getDuration method now uses the new Pointer downTime and upTime values, meaning it will accurately report the duration of when any button is being held down, not just the primary one. Fix #5112 (thanks @veleek)
  • The BaseShader default vertex shader now includes the outTexCoord vec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok)
  • When using the GameObjectCreator for Containers you can now specify the children property in the configuration object.
  • Textures.Parsers.JSONHash will now perform a hasOwnProperty check when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes from JSON.parse. Fix #4768 (thanks @RollinSafary)
  • The Camera3D Plugin has been rebuilt for Phaser 3.50 and the webpack config updated. This plugin is now considered deprecated and will not be updated beyond this release.
  • Tween.seek will no longer issue a console warning for 'Tween.seek duration too long', it's now up to you to check on the performance of tween seeking.
  • If inputWindowEvents is set in the Game Config, then the MouseManager will now listen for the events on window.top instead of just window, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in a try/catch block, as not all sites allow access to window.top (specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow)
  • MouseManager.isTop is a new boolean read-only property that flags if the mouse event listeners were attached to window.top (true), or just window (false). By default Phaser will attempt window.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back to window in those cases and set this property to false (thanks BunBunBun)
  • Types.GameObjects.Text.GetTextSizeObject is a new type def for the GetTextSize function results.
  • Utils.Array.StableSort has been recoded. It's now based on Two-Screens stable sort 0.1.8 and has been updated to fit into Phaser better and no longer create any window bound objects. The inplace function has been removed, just call StableSort(array) directly now. All classes that used StableSort.inplace have been updated to call it directly.
  • If a Scene is paused, or sent to sleep, it will automatically call Keyboard.resetKeys. This means that if you hold a key down, then sleep or pause a Scene, then release the key and resume or wake the Scene, it will no longer think it is still being held down (thanks @samme)
  • Actions.setOrigin will now call updateDisplayOrigin on the items array, otherwise the effects can't be seen when rendering.
  • You can now set the ArcadeWorld.fixedStep property via the ArcadeWorldConfig object (thanks @samme)
  • Utils.Array.NumerArray can now accept the start and end parameters in reverse order, i.e. 10, 1 will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.
  • DataManager.Events.DESTROY is a new event that the Data Manager will listen for from its parent and then call its own destroy method when received.
  • The Quaternion class constructor will now default the values to 0,0,0,1 if they're not provided, making it an identity quaternion, rather than the 0,0,0,0 it was before.
  • You can now set the ParticleEmitter.reserve value via the emitter configuration object (thanks @vforsh)
  • Setting the pixelArt config option will now set antialiasGL to false, as well as antialias. Fix #5309 (thanks @Vegita2)
  • The Shape class now includes the ComputedSize component properties and methods directly in the class, rather than applying as a mixin. setSize is now flagged as being private, because it shouldn't be used on Shape classes, which was leading to confusion as it appeared in the public-facing API. Fix #4811 (thanks @aolsx)
  • The Loader.maxParallelDownloads value is now set to 6 if running on Android, or 32 on any other OS. This avoids net::ERR_FAILED issues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary)
  • When running an Arcade Physics overlap test against a StaticBody, it will no longer set the blocked states of the dynamic body. If you are doing a collision test, they will still be set, but they're skipped for overlap-only tests. Fix #4435 (thanks @samme)
  • The Line Game Object will now default its width and height to 1, rather than zero. This allows you to give Line objects a physics body (although you will still need to re-adjust the center of the body manually). Fix #4596 (thanks @andrewaustin)
  • Internally, the Quaternion class now has 4 new private properties: _x, _y, _z and _w and 4 new getters and setters for the public versions. It also now passes most methods via set to allow for the onChange callback to be invoked. This does not change the public-facing API.
  • Group now extends EventEmitter, allowing you to emit custom events from within a Group.
  • Device.Audio.wav now uses audio/wav as the canPlayType check string, instead of audio/wav; codecs="1", which should allow iOS13 to play wav files again.
  • In the Loader.FileTypes.TextFile config you can now override the type and cache destination for the file.
  • Loader.MultiFile will now parse the given files array and only add valid entries into the file list, allowing multifiles to now have optional file entries.
  • The ParticleEmitter.tint value is now 0xffffff (previously, it was 0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh)
  • SceneManager.start will now reset the SceneSystems.sceneUpdate reference to NOOP. This gets set back to the Scene update method again during bootScene (if it has one) and stops errors with external plugins and multi-part files that may trigger update before create has been called. Fix #4629 (thanks @Osmose)
  • Phaser.Scene.renderer is a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.
  • The CanvasRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.
  • Since iOS 13, iPads now identify as MacOS devices. A new maxTouchPoint check is now part of the Device.OS tests, stopping iPads from being flagged as desktop devices. Fix #5389 (thanks @SBCGames)
  • The BitmapMask.prevFramebuffer property has been removed as it's no longer required, due to the fbo stack in the renderer.
  • The TextureManager.addGLTexture method has been updated so that the width and height parameters are now optional. If not provided, and if available, they will be read from the given WebGLTexture instead (thanks @hexus)
  • GameObjects.Components.Depth.depthList is a new property that all Game Objects that have the Depth Component now have. It contains a reference to the List responsible for managing the depth sorting of the Game Object. This is typically the Scene Display List, but can also be a Layer. It allows the Depth component to queue a depth sort directly on the list it belongs to now, rather than just the Scene.
  • The WebAudioSoundManager will no longer try to unlock itself if the Game hasn't already booted and been added to the DOM. It will now wait for the BOOT event and unlock based on that. Fix #5439 (thanks @samme)

Bug Fixes

  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)
  • The GridAlign action didn't work if only the height parameter was set. Fix #5019 (thanks @halilcakar)
  • The Color.HSVToRGB function has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX)
  • Previously, the easeParams array within a Tweens props object, or a multi-object tween, were ignored and it was only used if set on the root Tween object. It will now work correctly set at any depth. Fix #4292 (thanks @willblackmore)
  • When using Camera.setRenderToTexture its zoom and rotation values would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok)
  • GameObjects.Shape.Grid would render a white fill even if you passed undefined as the fill color in the constructor. It now doesn't render cells if no fill color is given.
  • The onMouse events in the Input Manager didn't reset the activePointer property to the mouse, meaning on dual-input systems such as Touch Screen devices, the active pointer would become locked to whichever input method was used first. Fix #4615 #5232 (thanks @mmolina01 @JstnPwll @Legomite)
  • The Scale Managers GetScreenOrientation function will now check for window.orientation first, because iOS mobile browsers have an incomplete implementation of the Screen API, forcing us to use the window value as a priority. This means the Scale Manager will now emit orientationchange events correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu)
  • Time.Clock.addEvent can now take an instance of a TimerEvent as its parameter. Fix #5294 (thanks @samme @EmilSV)
  • GameConfig.audio now defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)
  • The Loader.path was being added to the File URL even if the URL was absolute. This is now checked for and the path is not applied unless the URL is relative (thanks @firesoft)
  • Group.getMatching would always return an empty array. It now returns matching children (thanks @samme)
  • The ParticleManagerWebGLRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in follow offsets separately. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers. Fix #5319 #5195 #4739 #4691 (thanks @vforsh @condeagustin @IvanDem @Formic)
  • The ParticleManagerCanvasRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also uses setToContext internally. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers, or having the Camera zoomed, running under Canvas. Fix #4908 #4531 #4131 (thanks @smjnab @SirLink @jhooper04)
  • The Graphics WebGL Renderer will now default to pathOpen = true. This fixes issues under WebGL where, for example, adding an arc and calling strokePath, without first calling beginPath will no longer cause rendering artefacts when WebGL tries to close the path with a single tri.
  • Graphics.strokeRoundedRect now issues moveTo commands as part of the drawing sequence, preventing issues under WebGL where on older Android devices it would project additional vertices into the display. Fix #3955 (thanks @alexeymolchan)
  • Creating a Bitmap Mask from a texture atlas that was then used to mask another Game Object also using that same texture atlas would throw the error GL_INVALID_OPERATION : glDrawArrays: Source and destination textures of the draw are the same.. It now renders as expected. Fix #4675 (thanks @JacobCaron)
  • When using the same asset for a Game Object to be used as a mask, it would make other Game Objects using the same asset, that appeared above the mask in the display list, to not render. Fix #4767 (thanks @smjnab)
  • When taking a snapshot in WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in the WebGLSnapshot function. Fix #4956 (thanks @gammafp @telinc1)
  • Particles.EmitterOp.setMethods will now reset both onEmit and onUpdate to their default values. This allows you to reconfigure an emitter op with a new type of value and not have it stuck on the previous one. Fix #3663 (thanks @samme)
  • Particles.EmitterOp now cleanly separates between the different types of property configuration options. start | end will now ease between the two values, min | max will pick a random value between them and random: [] will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)
  • When setting both transparent: true and backgroundColor in the Game Config, it would ignore the transparency and use the color anyway. If transparent, the game is now fully transparent. Fix #5362 (thanks @Hoshinokoe)
  • The Ellipse Game Object now will update the width, height, and geometric position in the setSize method (thanks @PhaserEditor2D)
  • When measuring the last word in a line in a Text Game Object, it no longer adds extra white space to the end (thanks @rexrainbow)
  • Utils.Array.Remove would return an incorrect array of removed elements if one of the items to be removed was skipped in the array. Fix #5398 (thanks @year221)
  • Geom.Intersects.TriangleToLine wouldn't return true if the start or end of the Line fell inside the Triangle, only if the entire Line did. It now checks the start and end points correctly. (thanks @wiserim)
  • Using a Bitmap Mask and a Blend Mode in WebGL would reset the blend mode when the mask was rendered, causing the Game Object to have no blend mode. Fix #5409 (thanks @jcyuan)
  • BitmapMask would become corrupted when resizing the Phaser Game, either via the Scale Manager or directly, because the framebuffer and texture it used for rendering was still at the old dimensions. The BitmapMask now listens for the Renderer RESIZE event and re-creates itself accordingly. Fix #5399 (thanks @Patapits)

Misc Changes

Loader Cache Changes

When loading any of the file types listed below it will no longer store the data file in the cache. For example, when loading a Texture Atlas using a JSON File, it used to store the parsed image data in the Texture Manager and also store the JSON in the JSON Cache under the same key. This has changed in 3.50. The data files are no longer cached, as they are not required by the textures once parsing is completed, which happens during load. This helps free-up memory. How much depends on the size of your data files. And also allows you to easily remove textures based on just their key, without also having to clear out the corresponding data cache.

  • AtlasJSONFile no longer stores the JSON in the JSON Cache once the texture has been created.
  • AtlasXMLFile no longer stores the XML in the XML Cache once the texture has been created.
  • UnityAtlasFile no longer stores the Text in the Text Cache once the texture has been created.
  • BitmapFontFile no longer stores the XML in the XML Cache once the texture has been created.
  • You can now use TextureManager.remove to remove a texture and not have to worry about clearing the corresponding JSON or XML cache entry as well in order to reload a new texture using the same key. Fix #5323 (thanks @TedGriggs)

Lights 2D Updates

The Light Game Object has been rewritten so it now extends the Geom.Circle object, as they shared lots of the same properties and methods anyway. This has cut down on duplicate code massively.

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

Removal of 'resolution' property from across the API

For legacy reasons, Phaser 3 has never properly supported HighDPI devices. It will render happily to them of course, but wouldn't let you set a 'resolution' for the Canvas beyond 1. Earlier versions of 3.x had a resolution property in the Game Config, but it was never fully implemented (for example, it would break zooming cameras). When the Scale Manager was introduced in v3.16 we forced the resolution to be 1 to avoid it breaking anything else internally.

For a long time, the 'resolution' property has been present - taunting developers and confusing new comers. In this release we have finally gone through and removed all references to it. The Game Config option is now gone, it's removed from the Scale Manager, Base Camera and everywhere else where it matters. As much as we would have liked to implement the feature, we've spent too long without it, and things have been built around the assumption it isn't present. The API just wouldn't cope with having it shoe-horned in at this stage. As frustrating as this is, it's even more annoying to just leave the property there confusing people and wasting CPU cycles. Phaser 4 has been built with HighDPI screens in mind from the very start, but it's too late for v3. The following changes are a result of this removal:

  • The Phaser.Scale.Events#RESIZE event no longer sends the resolution as a parameter.
  • The BaseCamera.resolution property has been removed.
  • The internal private BaseCamera._cx, _cy, _cw and _ch properties has been removed, use x, y, width and height instead.
  • The BaseCamera.preRender method no longer receives or uses the resolution parameter.
  • The Camera.preRender method no longer receives or uses the resolution parameter.
  • The CameraManager.onResize method no longer receives or uses the resolution parameter.
  • The Core.Config.resolution property has been removed.
  • The TextStyle.resolution property is no longer read from the Game Config. You can still set it via the Text Style config to a value other than 1, but it will default to this now.
  • The CanvasRenderer no longer reads or uses the Game Config resolution property.
  • The PipelineManager.resize method along with WebGLPipeline.resize and anything else that extends them no longer receives or uses the resolution parameter.
  • The WebGLRenderer.resize and onResize methods no longer receives or uses the resolution parameter.
  • The ScaleManager.resolution property has been removed and all internal use of it.

Removal of 'interpolationPercentage' parameter from across the API

Since v3.0.0 the Game Object render functions have received a parameter called interpolationPercentage that was never used. The renderers do not calculate this value and no Game Objects apply it, so for the sake of clairty, reducing code and removing complexity from the API it has been removed from every single function that either sent or expected the parameter. This touches every single Game Object and changes the parameter order as a result, so please be aware of this if you have your own custom Game Objects, or plugins, that implement their own render methods. In terms of surface API changes, you shouldn't notice anything at all from this removal.

Namespace Updates

  • The Phaser.Curves.MoveTo function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.DOM.GetInnerHeight function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Bob class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsManager class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsPlugin class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Particles.EmitterOp class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.GetTextSize function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.MeasureText function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.TextStyle function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Input.CreatePixelPerfectHandler function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapCirc function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapRect function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Tilemap namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Components namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.MatterGameObject class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.PointerConstraint class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetPhysicsPlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetScenePlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Structs.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Tilemaps.Parsers.Tiled function has now been exposed on the Phaser namespace (thanks @samme)
  • Every single Tilemap.Component function has now been made public. This means you can call the Component functions directly, should you need to, outside of the Tilemap system.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360 @volkans80 @jaabberwocky @maikthomas @atursams @LearningCode2023 @DylanC @BenjaminDRichards @rexrainbow @Riderrr @spwilson2 @EmilSV @PhaserEditor2D @Gangryong @vinerz @trynx @usufruct99 @pirateksh @justin-calleja @monteiz

3.50 Beta Testing Help

A special mention to the following who submitted feedback on the 3.50 Beta releases:

@gammafp Acorn @BlunT76 @PhaserEditor2D @samme @rexrainbow @vforsh @kainage @ccaleb @spayton @FloodGames @buzzjeux @jcyuan @MadDogMayCry0 @Patapits @MMontalto @SBCGames @juanitogan @Racoonacoon @EmilSV @telinc1 @d7561985 @RollinSafary

Sorry if I forgot you!

- JavaScript
Published by photonstorm over 5 years ago

phaser - Phaser v3.50.0

Version 3.50.0 - Subaru - 16th December 2020

Due to the massive amount of changes in 3.50 this Change Log is, by its nature, very long. It's important to scan through it, especially if you're porting a game from an earlier version of Phaser to 3.50. However, if you're after more top-level descriptions of what's new, with example code, then please see the posts we will be making to the Phaser site and Phaser Patreon in the coming months after release. We have also updated the Phaser 3 Examples site, so that every single example up there has been rewritten for 3.50, so you don't have to struggle working through old or deprecated syntax. Virtually all new features are covered in new examples, as well.

With that said, we've tried to organize the Change Log into commonly themed sections to make it more digestible, but we appreciate there is a lot here. Please don't feel overwhelmed! If you need clarification about something, join us on the Phaser Discord and feel free to ask.

WebGL Pipelines and Post Processing

WebGL Pipelines are responsible for the rendering of all Game Objects in Phaser and they have had a complete rewrite in 3.50. This was to allow for the introduction of post processing pipelines, now readily available to be created from the new Post FX Pipeline class. The changes in this area have been extensive, so if you use custom WebGL Pipelines in your game already, you must update your code to use Phaser 3.50.

Pipeline Manager

The WebGL.PipelineManager is a new class that is responsible for managing all of the WebGL Pipelines in Phaser. An instance of the Pipeline Manager is created by the WebGL Renderer and is available under the pipelines property. This means that the WebGL Renderer no longer handles pipelines directly, causing the following API changes:

  • WebGLRenderer.pipelines is no longer a plain object containing pipeline instances. It's now an instance of the PipelineManager class. This instance is created during the init and boot phase of the renderer.
  • The WebGLRenderer.currentPipeline property no longer exists, instead use PipelineManager.current.
  • The WebGLRenderer.previousPipeline property no longer exists, instead use PipelineManager.previous.
  • The WebGLRenderer.hasPipeline method no longer exists, instead use PipelineManager.has.
  • The WebGLRenderer.getPipeline method no longer exists, instead use PipelineManager.get.
  • The WebGLRenderer.removePipeline method no longer exists, instead use PipelineManager.remove.
  • The WebGLRenderer.addPipeline method no longer exists, instead use PipelineManager.add.
  • The WebGLRenderer.setPipeline method no longer exists, instead use PipelineManager.set.
  • The WebGLRenderer.rebindPipeline method no longer exists, instead use PipelineManager.rebind.
  • The WebGLRenderer.clearPipeline method no longer exists, instead use PipelineManager.clear.

The Pipeline Manager also offers the following new features:

  • The PipelineManager.resize method automatically handles resize events across all pipelines.
  • The PipelineManager.preRender method calls the pre-render method of all pipelines.
  • The PipelineManager.render method calls the render method of all pipelines.
  • The PipelineManager.postRender method calls the post-render method of all pipelines.
  • The PipelineManager.setMulti method automatically binds the Multi Texture Pipeline, Phasers default.
  • The PipelineManager.clear method will clear the pipeline, store it in previous and free the renderer.
  • The PipelineManager.rebind method will reset the rendering context and restore the previous pipeline, if set.
  • The PipelineManager.copyFrame method will copy a source Render Target to the target Render Target, optionally setting the brightness of the copy.
  • The PipelineManager.blitFrame method will copy a source Render Target to the target Render Target. Unlike copyFrame no resizing takes place and you can optionally set the brightness and erase mode of the copy.
  • The PipelineManager.copyFrameRect method binds the source Render Target and then copies a section of it to the target using gl.copyTexSubImage2D rather than a shader, making it much faster if you don't need blending or preserving alpha details.
  • The PipelineManager.copyToGame method pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws the source Render Target to it. Use when you need to render the final result to the game canvas.
  • The PipelineManager.drawFrame method will copy a source Render Target, optionally to a target Render Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy.
  • The PipelineManager.blendFrames method 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 PipelineManager.blendFramesAdditive method 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 PipelineManager.clearFrame method clears the given Render Target.

New constants have been created to help you reference a pipeline without needing to use strings:

  • Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE for the Bitmap Mask Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE for the Light 2D Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE for the Single Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE for the Multi Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE for the Rope Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINE for the Point Light Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINE for the Post FX Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINE for the Utility Pipeline.

All Game Objects have been updated to use the new constants and Pipeline Manager.

Post FX Pipeline

The Post FX Pipeline is a brand new and special kind of pipeline specifically for handling post processing effects in Phaser 3.50.

Where-as a standard Pipeline allows you to control the process of rendering Game Objects by configuring the shaders and attributes used to draw them, a Post FX Pipeline is designed to allow you to apply processing after the Game Object/s have been rendered.

Typical examples of post processing effects are bloom filters, blurs, light effects and color manipulation.

The pipeline works by creating a tiny vertex buffer with just one single hard-coded quad in it. Game Objects can have a Post Pipeline set on them, which becomes their own unique pipeline instance. Those objects are then rendered using their standard pipeline, but are redirected to the Render Targets owned by the post pipeline, which can then apply their own shaders and effects, before passing them back to the main renderer.

The following properties and methods are available in the new PostFXPipeline class:

  • The PostFXPipeline.gameObject property is a reference to the Game Object that owns the Post Pipeline, if any.
  • The PostFXPipeline.colorMatrix property is a Color Matrix instance used by the draw shader.
  • The PostFXPipeline.fullFrame1 property is a reference to the fullFrame1 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.fullFrame2 property is a reference to the fullFrame2 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.halfFrame1 property is a reference to the halfFrame1 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.halfFrame2 property is a reference to the halfFrame2 Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing.
  • The PostFXPipeline.copyFrame method will copy a source Render Target to the target Render Target, optionally setting the brightness of the copy.
  • The PostFXPipeline.blitFrame method will copy a source Render Target to the target Render Target. Unlike copyFrame no resizing takes place and you can optionally set the brightness and erase mode of the copy.
  • The PostFXPipeline.copyFrameRect method binds the source Render Target and then copies a section of it to the target using gl.copyTexSubImage2D rather than a shader, making it much faster if you don't need blending or preserving alpha details.
  • The PostFXPipeline.copyToGame method pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws the source Render Target to it. Use when you need to render the final result to the game canvas.
  • The PostFXPipeline.drawFrame method will copy a source Render Target, optionally to a target Render Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy.
  • The PostFXPipeline.blendFrames method 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 PostFXPipeline.blendFramesAdditive method 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 PostFXPipeline.clearFrame method clears the given Render Target.
  • The PostFXPipeline.bindAndDraw method binds this pipeline and draws the source Render Target to the target Render Target. This is typically the final step taken in when post processing.

Renamed WebGL Pipelines

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

There is also the new GraphicsPipeline. Previously, the TextureTintPipeline was responsible for rendering all Sprites, Graphics, and Shape objects. Now, it only renders Sprites. All Graphics and Shapes are handled by the new GraphicsPipeline, which uses its own shaders. See below for details about this change.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

WebGL Pipelines Updates

Further pipeline changes are as follows:

  • None of the shaders or pipelines use the uViewMatrix and uModelMatrix uniforms any longer. These were always just plain identity matrices, so there is no point spending CPU and GPU time to set them as uniforms or use them in the shaders. Should you need these uniforms, you can add them to your own custom pipelines.
  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.
  • The WebGLPipeline.shouldFlush method now accepts an optional parameter amount. If given, it will return true if the amount to be added to the vertex count exceeds the vertex capacity. The Multi Pipeline has been updated to now use this method instead of performing the comparison multiple times itself.
  • The RopePipeline now extends MultiPipeline and just changes the topology, vastly reducing the file size.
  • The WebGLPipeline.flushLocked property has been removed. A pipeline can never flush in the middle of a flush anyway, so it was just wasting CPU cycles being set.
  • WebGLPipeline.manager is a new property that is a reference to the WebGL Pipeline Manager.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLPipeline.forceZero is a new boolean property that sets if the pipeline should force the use of texture zero.
  • WebGLPipeline.hasBooted is a new boolean property that is set once the pipeline has finished setting itself up and has booted.
  • WebGLPipeline.isPostFX is a new boolean property that is only set by Post FX Pipelines to help identify them.
  • WebGLPipeline.renderTargets is a new property that holds an array of WebGL Render Targets belonging to the pipeline.
  • WebGLPipeline.currentRenderTarget is a new property that holds a reference to the currently bound Render Target.
  • WebGLPipeline.shaders is a new property that holds an array of all WebGLShader instances that belong to the pipeline.
  • WebGLPipeline.currentShader is a new property that holds a reference to the currently active shader within the pipeline.
  • WebGLPipeline.config is a new property that holds the pipeline configuration object used to create it.
  • WebGLPipeline.projectionMatrix is a new property that holds a Matrix4 used as the projection matrix for the pipeline.
  • WebGLPipeline.setProjectionMatrix is a new method that allows you to set the ortho projection matrix of the pipeline.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLPipeline.setShader is a new method that allows you to set the currently active shader within the pipeline.
  • WebGLPipeline.getShaderByName is a new method that allows you to get a shader from the pipeline based on its name.
  • WebGLPipeline.setShadersFromConfig is a new method that destroys all current shaders and creates brand new ones parsed from the given config object. This is part of the pipeline boot process, but also exposed should you need to call it directly.
  • WebGLPipeline.setGameObject is a new method that custom pipelines can use in order to perform pre-batch tasks for the given Game Object.
  • WebGLPipeline.setVertexBuffer is a new method that checks if the pipelines vertex buffer is active, or not, and if not, binds it as the active buffer. This used to be performed by the WebGL Renderer, but pipelines now manage this directly.
  • WebGLPipeline.preBatch is a new method that is called when a new quad is about to be added to the batch. This is used by Post FX Pipelines to set frame buffers.
  • WebGLPipeline.postBatch is a new method that is called after a quad has been added to the batch. This is used by Post FX Pipelines to apply post processing.
  • WebGLPipeline.unbind is a new method that unbinds the current Render Target, if one is set.
  • WebGLPipeline.batchVert is a new method that adds a single vertex to the vertex buffer and increments the count by 1.
  • WebGLPipeline.batchQuad is a new method that adds a single quad (6 vertices) to the vertex buffer and increments the count, flushing first if adding the quad would exceed the batch limit.
  • WebGLPipeline.batchTri is a new method that adds a single tri (3 vertices) to the vertex buffer and increments the count, flushing first if adding the tri would exceed the batch limit.
  • WebGLPipeline.drawFillRect is a new method that pushes a filled rectangle into the vertex batch.
  • WebGLPipeline.setTexture2D is a new method that sets the texture to be bound to the next available texture unit.
  • WebGLPipeline.bindTexture is a new method that immediately activates the given WebGL Texture and binds it to the requested slot.
  • WebGLPipeline.bindRenderTarget is a new method that binds the given Render Target to a given texture slot.
  • WebGLPipeline.setTime is a new method that gets the current game loop duration to the given shader uniform.

Pipeline Hooks

The WebGLPipeline class has lots of new hooks you can use. These are all empty by default so you can safely override them in your own classes to take advantage of them:

  • WebGLPipeline.onBoot is a new hook you can override in your own pipelines that is called when the pipeline has booted.
  • WebGLPipeline.onResize is a new hook you can override in your own pipelines that is called when the pipeline is resized.
  • WebGLPipeline.onDraw is a new hook you can override in your own pipelines that is called by Post FX Pipelines every time postBatch is invoked.
  • WebGLPipeline.onActive is a new hook you can override in your own pipelines that is called every time the Pipeline Manager makes the pipeline the active pipeline.
  • WebGLPipeline.onBind is a new hook you can override in your own pipelines that is called every time a Game Object asks the Pipeline Manager to use this pipeline, even if it's already active.
  • WebGLPipeline.onRebind is a new hook you can override in your own pipelines that is called every time the Pipeline Manager needs to reset and rebind the current pipeline.
  • WebGLPipeline.onBatch is a new hook you can override in your own pipelines that is called after a new quad (or tri) has been added to the batch.
  • WebGLPipeline.onPreBatch is a new hook you can override in your own pipelines that is called before a new Game Object is about to process itself through the batch.
  • WebGLPipeline.onPostBatch is a new hook you can override in your own pipelines that is called after a new Game Object has added itself to the batch.
  • WebGLPipeline.onPreRender is a new hook you can override in your own pipelines that is called once, per frame, right before anything has been rendered.
  • WebGLPipeline.onRender is a new hook you can override in your own pipelines that is called once, per frame, by every Camera in the Scene that wants to render, at the start of the render process.
  • WebGLPipeline.onPostRender is a new hook you can override in your own pipelines that is called once, per frame, after all rendering has happened and snapshots have been taken.
  • WebGLPipeline.onBeforeFlush is a new hook you can override in your own pipelines that is called immediately before the gl.bufferData and gl.drawArrays calls are made, so you can perform any final pre-render modifications.
  • WebGLPipeline.onAfterFlush is a new hook you can override in your own pipelines that is called after gl.drawArrays, so you can perform additional post-render effects.

Pipeline Events

The WebGLPipeline class now extends the Event Emitter and emits the following new events:

  • The WebGL.Pipelines.Events.AFTER_FLUSH event is dispatched by a WebGL Pipeline right after it has issued a drawArrays command.
  • The WebGL.Pipelines.Events.BEFORE_FLUSH event is dispatched by a WebGL Pipeline right before it is about to flush.
  • The WebGL.Pipelines.Events.BIND event is dispatched by a WebGL Pipeline when it is bound by the Pipeline Manager.
  • The WebGL.Pipelines.Events.BOOT event is dispatched by a WebGL Pipeline when it has finished booting.
  • The WebGL.Pipelines.Events.DESTROY event is dispatched by a WebGL Pipeline when it begins its destruction process.
  • The WebGL.Pipelines.Events.REBIND event is dispatched by a WebGL Pipeline when the Pipeline Manager resets and rebinds it.
  • The WebGL.Pipelines.Events.RESIZE event is dispatched by a WebGL Pipeline when it is resized, usually as a result of the Renderer.

Pipeline Uniform Changes

WebGLShaders have a uniforms object that is automatically populated when the shader is created. It scans all of the active uniforms from the compiled shader and then builds an object containing their WebGLUniformLocation and a value cache.

This saves redundant gl operations for both looking-up uniform locations and setting their values if they're already the currently set values by using the local cache instead.

The WebGLPipeline classes offer a means to set uniform values on the shader (or shaders) belonging to the pipeline. Previously, calling a method such as setFloat3 on a pipeline would pass that call over to WebGLRenderer. The renderer would first check to see if the pipeline program was current, and if not, make it so, before then looking up the uniform location and finally setting it. This is a lot of steps to take for pipelines that potentially need to change uniforms for every Game Object they render.

Under the new methods, and using the new pre-cached uniform locations and values, these extra steps are skipped. The uniform value is set directly, no shader binding takes place and no location look-up happens. This dramatically reduces the number of WebGL ops being issued per frame. To clearly differentiate these pipeline methods, we have renamed them. The new method names are as follows:

  • WebGLPipeline.set1f will set a 1f uniform based on the given name.
  • WebGLPipeline.set2f will set a 2f uniform based on the given name.
  • WebGLPipeline.set3f will set a 3f uniform based on the given name.
  • WebGLPipeline.set4f will set a 4f uniform based on the given name.
  • WebGLPipeline.set1fv will set a 1fv uniform based on the given name.
  • WebGLPipeline.set2fv will set a 2fv uniform based on the given name.
  • WebGLPipeline.set3fv will set a 3fv uniform based on the given name.
  • WebGLPipeline.set4fv will set a 4fv uniform based on the given name.
  • WebGLPipeline.set1iv will set a 1iv uniform based on the given name.
  • WebGLPipeline.set2iv will set a 2iv uniform based on the given name.
  • WebGLPipeline.set3iv will set a 3iv uniform based on the given name.
  • WebGLPipeline.set4iv will set a 4iv uniform based on the given name.
  • WebGLPipeline.set1i will set a 1i uniform based on the given name.
  • WebGLPipeline.set2i will set a 2i uniform based on the given name.
  • WebGLPipeline.set3i will set a 3i uniform based on the given name.
  • WebGLPipeline.set4i will set a 4i uniform based on the given name.
  • WebGLPipeline.setMatrix2fv will set a matrix 2fv uniform based on the given name.
  • WebGLPipeline.setMatrix3fv will set a matrix 3fv uniform based on the given name.
  • WebGLPipeline.setMatrix4fv will set a matrix 4fv uniform based on the given name.

If your code uses any of the old method names, please update them using the list below:

  • WebGLPipeline.setFloat1 has been removed. Please use set1f instead.
  • WebGLPipeline.setFloat2 has been removed. Please use set2f instead.
  • WebGLPipeline.setFloat3 has been removed. Please use set3f instead.
  • WebGLPipeline.setFloat4 has been removed. Please use set4f instead.
  • WebGLPipeline.setFloat1v has been removed. Please use set1fv instead.
  • WebGLPipeline.setFloat2v has been removed. Please use set2fv instead.
  • WebGLPipeline.setFloat3v has been removed. Please use set3fv instead.
  • WebGLPipeline.setFloat4v has been removed. Please use set4fv instead.
  • WebGLPipeline.setInt1 has been removed. Please use set1i instead.
  • WebGLPipeline.setInt2 has been removed. Please use set2i instead.
  • WebGLPipeline.setInt3 has been removed. Please use set3i instead.
  • WebGLPipeline.setInt4 has been removed. Please use set4i instead.
  • WebGLPipeline.setMatrix1 has been removed. Please use setMatrix2fv instead.
  • WebGLPipeline.setMatrix2 has been removed. Please use setMatrix3fv instead.
  • WebGLPipeline.setMatrix3 has been removed. Please use setMatrix4fv instead.

Game Object Pipeline Component Updates

To support the new Post Pipelines in 3.50, the Pipeline Component which most Game Objects inherit has been updated. That means the following new properties and methods are available on all Game Objects that have this component, such as Sprite, Layer, Rope, etc.

  • hasPostPipeline is a new boolean property that indicates if the Game Object has one, or more post pipelines set.
  • postPipelines is a new property that contains an array of Post Pipelines owned by the Game Object.
  • pipelineData is a new object object to store pipeline specific data in.
  • The setPipeline method has been updated with 2 new parameters: pipelineData and copyData. These allow you to populate the pipeline data object during setting.
  • You can now pass a pipeline instance to the setPipeline method, as well as a string.
  • setPostPipeline is a new method that allows you to set one, or more, Post FX Pipelines on the Game Object. And optionally set the pipeline data with them.
  • setPipelineData is a new method that allows you to set a key/value pair into the pipeline data object in a chainable way.
  • getPostPipeline is a new method that will return a Post Pipeline instance from the Game Object based on the given string, function or instance.
  • The resetPipeline method has two new parameters resetPostPipeline and resetData, both false by default, that will reset the Post Pipelines and pipeline data accordingly.
  • resetPostPipeline is a new method that will specifically reset just the Post Pipelines, and optionally the pipeline data.
  • removePostPipeline is a new method that will destroy and remove the given Post Pipeline from the Game Object.

Utility Pipeline

The Utility Pipeline is a brand new default special-use WebGL Pipeline that is created by and belongs to the Pipeline Manager.

It provides 4 shaders and handy associated methods:

1) Copy Shader. A fast texture to texture copy shader with optional brightness setting. 2) Additive Blend Mode Shader. Blends two textures using an additive blend mode. 3) Linear Blend Mode Shader. Blends two textures using a linear blend mode. 4) Color Matrix Copy Shader. Draws a texture to a target using a Color Matrix.

You do not extend this pipeline, but instead get a reference to it from the Pipeline Manager via the setUtility method. You can also access its methods, such as copyFrame, directly from both the Pipeline Manager and from Post FX Pipelines, where its features are most useful.

This pipeline provides methods for manipulating framebuffer backed textures, such as copying or blending one texture to another, copying a portion of a texture, additively blending two textures, flipping textures and more. All essential and common operations for post processing.

The following properties and methods are available in the new UtilityPipeline class:

  • The UtilityPipeline.colorMatrix property is an instance of a ColorMatrix class, used by the draw shader.
  • The UtilityPipeline.copyShader property is a reference to the Copy Shader.
  • The UtilityPipeline.addShader property is a reference to the additive blend shader.
  • The UtilityPipeline.linearShader property is a reference to the linear blend shader.
  • The UtilityPipeline.colorMatrixShader property is a reference to the color matrix (draw) shader.
  • The UtilityPipeline.fullFrame1 property is a full sized Render Target that can be used as a temporary buffer during post processing calls.
  • The UtilityPipeline.fullFrame2 property is a full sized Render Target that can be used as a temporary buffer during post processing calls.
  • The UtilityPipeline.halfFrame1 property is a half sized Render Target that can be used as a temporary buffer during post processing calls, where a small texture is required for more intensive operations.
  • The UtilityPipeline.halfFrame2 property is a half sized Render Target that can be used as a temporary buffer during post processing calls, where a small texture is required for more intensive operations.
  • The UtilityPipeline.copyFrame method will copy a source Render Target to the target Render Target, optionally setting the brightness of the copy.
  • The UtilityPipeline.blitFrame method will copy a source Render Target to the target Render Target. Unlike copyFrame no resizing takes place and you can optionally set the brightness and erase mode of the copy.
  • The UtilityPipeline.copyFrameRect method binds the source Render Target and then copies a section of it to the target using gl.copyTexSubImage2D rather than a shader, making it much faster if you don't need blending or preserving alpha details.
  • The UtilityPipeline.copyToGame method pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws the source Render Target to it. Use when you need to render the final result to the game canvas.
  • The UtilityPipeline.drawFrame method will copy a source Render Target, optionally to a target Render Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy.
  • The UtilityPipeline.blendFrames method 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 UtilityPipeline.blendFramesAdditive method 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 UtilityPipeline.clearFrame method clears the given Render Target.
  • The UtilityPipeline.setUVs method allows you to set the UV values for the 6 vertices that make-up the quad belonging to the Utility Pipeline.
  • The UtilityPipeline.setTargetUVs method sets the vertex UV coordinates of the quad used by the shaders so that they correctly adjust the texture coordinates for a blit frame effect.
  • The UtilityPipeline.flipX method horizontally flips the UV coordinates of the quad used by the shaders.
  • The UtilityPipeline.flipY method vertically flips the UV coordinates of the quad used by the shaders.
  • The UtilityPipeline.resetUVs method resets the quad vertice UV values to their default settings.

Light Pipeline Update

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh Game Objects now support rendering with normal maps.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Point Lights Pipeline

The Point Light Pipeline is a brand new pipeline in 3.50 that was creates specifically for rendering the new Point Light Game Objects in WebGL.

It extends the WebGLPipeline and sets the required shader attributes and uniforms for Point Light rendering.

You typically don't access or set the pipeline directly, but rather create instances of the Point Light Game Object instead. However, it does have the following unique methods:

  • The PointLightPipeline.batchPointLight method is a special-case method that is called directly by the Point Light Game Object during rendering and allows it to add itself into the rendering batch.
  • The PointLightPipeline.batchLightVert method is a special internal method, used by batchPointLight that adds a single Point Light vert into the batch.

Graphics Pipeline and Graphics Game Object Changes

The Graphics Pipeline is a new pipeline added in 3.50 that is responsible for rendering Graphics Game Objects and all of the Shape Game Objects, such as Arc, Rectangle, Star, etc. Due to the new pipeline some changes have been made:

  • The Graphics Pipeline now uses much simpler vertex and fragment shaders with just two attributes (inPosition and inColor), making the vertex size and memory-use 57% smaller.
  • The private _tempMatrix1, 2, 3 and 4 properties have all been removed from the pipeline.
  • A new public calcMatrix property has been added, which Shape Game Objects use to maintain transform state during rendering.
  • The Graphics Pipeline no longer makes use of tintEffect or any textures.
  • Because Graphics and Shapes now render with their own pipeline, you are able to exclude the pipeline and those Game Objects entirely from custom builds, further reducing the final bundle size.

As a result of these changes the following features are no longer available:

  • Graphics.setTexture has been removed. You can no longer use a texture as a 'fill' for a Graphic. It never worked with any shape other than a Rectangle, anyway, due to UV mapping issues, so is much better handled via the new Mesh Game Object.
  • Graphics._tempMatrix1, 2 and 3 have been removed. They're not required internally any longer.
  • Graphics.renderWebGL now uses the standard GetCalcMatrix function, cutting down on duplicate code significantly.

Single Pipeline Update

There is a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGLShader

WebGLShader is a new class that is created and belongs to WebGL Pipeline classes. When the pipeline is created it will create a WebGLShader instance for each one of its shaders, as defined in the pipeline configuration.

This class encapsulates everything needed to manage a shader in a pipeline, including the shader attributes and uniforms, as well as lots of handy methods such as set2f, for setting uniform values on this shader. Uniform values are automatically cached to avoid unnecessary gl operations.

Typically, you do not create an instance of this class directly, as it works in unison with the pipeline to which it belongs. You can gain access to this class via a pipeline's shaders array, post-creation.

The following properties and methods are available in the new WebGLShader class:

  • The WebGLShader.pipeline property is a reference to the WebGL Pipeline that owns the WebGLShader instance.
  • The WebGLShader.name property is the name of the shader.
  • The WebGLShader.renderer property is a reference to the WebGL Renderer.
  • The WebGLShader.gl property is a reference to the WebGL Rendering Context.
  • The WebGLShader.program property is the WebGL Program created from the vertex and fragment shaders.
  • The WebGLShader.attributes property is an array of objects that describe the vertex attributes of the shader.
  • The WebGLShader.vertexComponentCount property is the total amount of vertex attribute components of 32-bit length.
  • The WebGLShader.vertexSize property is the size, in bytes, of a single vertex.
  • The WebGLShader.uniforms property is an object that is automatically populated with all active uniforms in the shader.
  • The WebGLShader.createAttributes method takes the vertex attributes config and parses it, creating the shader attributes. This is called automatically.
  • The WebGLShader.bind method sets the program the shader uses as being active. Called automatically when the parent pipeline needs this shader.
  • The WebGLShader.rebind method sets the program the shader uses as being active and resets all of the vertex attribute pointers.
  • The WebGLShader.setAttribPointers method sets the vertex attribute pointers. Called automatically during bind.
  • The WebGLShader.createUniforms method populates the uniforms object with details about all active uniforms.
  • The WebGLShader.hasUniform method returns a boolean if the given uniform exists.
  • The WebGLShader.resetUniform method resets the cached value for the given uniform.
  • The WebGLShader.setUniform1 method is an internal method used for setting a single value uniform on the shader.
  • The WebGLShader.setUniform2 method is an internal method used for setting a double value uniform on the shader.
  • The WebGLShader.setUniform3 method is an internal method used for setting a triple value uniform on the shader.
  • The WebGLShader.setUniform4 method is an internal method used for setting a quadruple value uniform on the shader.
  • The WebGLShader.set1f method sets a 1f uniform based on the given name.
  • The WebGLShader.set2f method sets a 2f uniform based on the given name.
  • The WebGLShader.set3f method sets a 3f uniform based on the given name.
  • The WebGLShader.set4f method sets a 4f uniform based on the given name.
  • The WebGLShader.set1fv method sets a 1fv uniform based on the given name.
  • The WebGLShader.set2fv method sets a 2fv uniform based on the given name.
  • The WebGLShader.set3fv method sets a 3fv uniform based on the given name.
  • The WebGLShader.set4fv method sets a 4fv uniform based on the given name.
  • The WebGLShader.set1iv method sets a 1iv uniform based on the given name.
  • The WebGLShader.set2iv method sets a 2iv uniform based on the given name.
  • The WebGLShader.set3iv method sets a 3iv uniform based on the given name.
  • The WebGLShader.set4iv method sets a 4iv uniform based on the given name.
  • The WebGLShader.set1i method sets a 1i uniform based on the given name.
  • The WebGLShader.set2i method sets a 2i uniform based on the given name.
  • The WebGLShader.set3i method sets a 3i uniform based on the given name.
  • The WebGLShader.set4i method sets a 4i uniform based on the given name.
  • The WebGLShader.setMatrix2fv method sets a matrix 2fv uniform based on the given name.
  • The WebGLShader.setMatrix3fv method sets a matrix 3fv uniform based on the given name.
  • The WebGLShader.setMatrix4fv method sets a matrix 4fv uniform based on the given name.
  • The WebGLShader.destroy method removes all external references and deletes the program and attributes.

Render Target

RenderTarget is a brand new class that encapsulates a WebGL framebuffer and the WebGL Texture that displays it. Instances of this class are typically created by, and belong to WebGL Pipelines, however other Game Objects and classes can take advantage of Render Targets as well.

The following properties and methods are available in the new RenderTexture class:

  • The RenderTarget.renderer property is a reference to the WebGL Renderer.
  • The RenderTarget.framebuffer property is the WebGLFramebuffer belonging to the Render Target.
  • The RenderTarget.texture property is a WebGLTexture belonging to the Render Target and bound to the framebuffer.
  • The RenderTarget.width property is the width of the Render Target.
  • The RenderTarget.height property is the height of the Render Target.
  • The RenderTarget.scale property is the scale of the Render Target, applied to the dimensions during resize.
  • The RenderTarget.minFilter property is the min filter of the texture.
  • The RenderTarget.autoClear property is a boolean that controls if the Render Target is automatically cleared when bound.
  • The RenderTarget.autoResize property is a boolean that controls if the Render Target is automatically resized if the WebGLRenderer resizes.
  • The RenderTarget.setAutoResize method lets you set the auto resize of the Render Target.
  • The RenderTarget.resize method lets you resize the Render Target.
  • The RenderTarget.bind method sets the Render Target as being the active fbo in the renderer and optionally clears and adjusts the viewport.
  • The RenderTarget.adjustViewport method sets the viewport to match the Render Target dimensions.
  • The RenderTarget.clear method disables the scissors, clears the Render Target and resets the scissors again.
  • The RenderTarget.unbind method flushes the renderer and pops the Render Target framebuffer from the stack.
  • The RenderTarget.destroy method removes all external references and deletes the framebuffer and texture.

WebGL Renderer

New WebGL Multi-Texture Support

The Multi Pipeline (previously called the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw-call bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.
  • The WebGL.Utils.getComponentCount function has been removed as this is no longer required internally.

WebGLRenderer New Features, Updates and API Changes

  • WebGLRenderer.instancedArraysExtension is a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.
  • WebGLRenderer.vaoExtension is a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.
  • WebGLRenderer.resetProgram is a new method that will rebind the current program, without flushing or changing any properties.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • WebGLRenderer.finalType is a new boolean property that signifies if the current Game Object being rendered is the final one in the list.
  • The WebGLRenderer.updateCanvasTexture method will now set gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL to true, which should stop issues where you update a Text Game Object, having added a Render Texture or Spine Game Object to the Scene after it, which switches the PMA setting. Fix #5064 #5155 (thanks @hugoruscitti @immangrove-supertree)
  • WebGLRenderer.previousPipeline is a new property that is set during a call to clearPipeline and used during calls to rebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.
  • The WebGLRenderer.rebindPipeline method has been changed slightly. Previously, you had to specify the pipelineInstance, but this is now optional. If you don't, it will use the new previousPipeline property instead. If not set, or none given, it will now return without throwing gl errors as well.
  • WebGLRenderer.defaultScissor is a new property that holds the default scissor dimensions for the renderer. This is modified during resize and avoids continuous array generation in the preRender loop.
  • The WebGLRenderer.nativeTextures array has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in the TextureSource objects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy.
  • The WebGLRenderer.deleteTexture method has a new optional boolean parameter reset which allows you to control if the WebGLRenderer.resetTextures method is called, or not, after the texture is deleted.
  • The WebGLRenderer.getMaxTextures method has been removed. This is no longer needed as you can use the WebGLRenderer.maxTextures property instead.
  • The WebGLRenderer.setProgram method now returns a boolean. true if the program was set, otherwise false.
  • WebGLRenderer.setFloat1 has been removed. Use WebGLPipeline.set1f or WebGLShader.set1f instead.
  • WebGLRenderer.setFloat2 has been removed. Use WebGLPipeline.set2f or WebGLShader.set2f instead.
  • WebGLRenderer.setFloat3 has been removed. Use WebGLPipeline.set3f or WebGLShader.set3f instead.
  • WebGLRenderer.setFloat4 has been removed. Use WebGLPipeline.set4f or WebGLShader.set4f instead.
  • WebGLRenderer.setFloat1v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set1fv instead.
  • WebGLRenderer.setFloat2v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set2fv instead.
  • WebGLRenderer.setFloat3v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set3fv instead.
  • WebGLRenderer.setFloat4v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set4fv instead.
  • WebGLRenderer.setInt1 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set1i instead.
  • WebGLRenderer.setInt2 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set2i instead.
  • WebGLRenderer.setInt3 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set3i instead.
  • WebGLRenderer.setInt4 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set4i instead.
  • WebGLRenderer.setMatrix2 has been removed. Use WebGLPipeline.setMatrix2fv or WebGLShader.setMatrix2fv instead.
  • WebGLRenderer.setMatrix3 has been removed. Use WebGLPipeline.setMatrix3fv or WebGLShader.setMatrix3fv instead.
  • WebGLRenderer.setMatrix4 has been removed. Use WebGLPipeline.setMatrix4fv or WebGLShader.setMatrix4fv instead.
  • The WebGLRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.
  • WebGLRenderer.fboStack is a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.
  • WebGLRenderer.pushFramebuffer is a new method that is used to push a framebuffer onto the fbo stack before setting it as the current framebuffer. This should now be called in place of setFramebuffer. Remember to call popFramebuffer after using it.
  • WebGLRenderer.popFramebuffer is a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.
  • WebGLRenderer.setFramebuffer has a new optional boolean parameter resetTextures which will reset the WebGL Textures, if set to true (which is the default).
  • WebGLRenderer.isBooted is a new boolean property that lets you know if the renderer has fully finished booting.
  • The WebGLRenderer now extends the Event Emitter, allowing you to listen to renderer specific events.
  • WebGLRenderer.defaultCamera has been removed as it's not used anywhere internally any longer.
  • The WebGLRenderer.setVertexBuffer method has been removed along with the WebGLRenderer.currentVertexBuffer property. This is now set directly by the WebGL Pipeline, as needed.
  • The WebGLRenderer.setIndexBuffer method has been removed along with the WebGLRenderer.currentIndexBuffer property. This is now set directly by the WebGL Pipeline, as needed.
  • WebGLRenderer.resetScissor is a new method that will reset the gl scissor state to be the current scissor, if there is one, without modifying the stack.
  • WebGLRenderer.resetViewport is a new method that will reset the gl viewport to the current renderer dimensions.
  • WebGLRenderer.renderTarget is a new property that contains a Render Target that is bound to the renderer and kept resized to match it.
  • WebGLRenderer.beginCapture is a new method that will bind the renderers Render Target, so everything drawn is redirected to it.
  • WebGLRenderer.endCapture is a new method that will unbind the renderers Render Target and return it, preventing anything else from being drawn to it.
  • WebGLRenderer.setProjectionMatrix is a new method that sets the global renderer projection matrix to the given dimensions.
  • WebGLRenderer.resetProjectionMatrix is a new method that resets the renderer projection matrix back to match the renderer size.
  • WebGLRenderer.getAspectRatio is a new method that returns the aspect ratio of the renderer.

WebGL ModelViewProjection Removed

The ModelViewProjection object contained a lot of functions that Phaser never used internally. Instead, the functions available in them were already available in the Math.Matrix4 class. So the pipelines have been updated to use a Matrix4 instead and all of the MVP functions have been removed. The full list of removed functions is below:

  • projIdentity has been removed.
  • projPersp has been removed.
  • modelRotateX has been removed.
  • modelRotateY has been removed.
  • modelRotateZ has been removed.
  • viewLoad has been removed.
  • viewRotateX has been removed.
  • viewRotateY has been removed.
  • viewRotateZ has been removed.
  • viewScale has been removed.
  • viewTranslate has been removed.
  • modelIdentity has been removed.
  • modelScale has been removed.
  • modelTranslate has been removed.
  • viewIdentity has been removed.
  • viewLoad2D has been removed.
  • projOrtho has been removed.

WebGL and Canvas Renderer Events

  • Phaser.Renderer.Events is a new namespace for events emitted by the Canvas and WebGL Renderers.
  • Renderer.Events.PRE_RENDER is a new event dispatched by the Phaser Renderer. This happens right at the start of the render process.
  • Renderer.Events.RENDER is a new event dispatched by the Phaser Renderer. This happens once for every camera, in every Scene at the start of its render process.
  • Renderer.Events.POST_RENDER is a new event dispatched by the Phaser Renderer. This happens right at the end of the render process.
  • Renderer.Events.RESIZE is a new event dispatched by the Phaser Renderer whenever it is resized.

Canvas Renderer Updates

  • CanvasRenderer.isBooted is a new boolean property that lets you know if the renderer has fully finished booting.
  • The CanvasRenderer now extends the Event Emitter, allowing you to listen to renderer specific events.

Camera - New Features, Updates and API Changes

The Camera API has changed in line with the new pipeline updates. To this end, the following changes have taken place:

The Camera class now inherits the Pipeline Component. This gives it new features, in line with the other pipelines changes in 3.50, such as Camera.setPipeline, Camera.setPostPipeline, Camera.setPipelineData and so on. This is a much more powerful and flexible way of setting camera effects, rather than it managing its own framebuffer and texture directly.

To that end, the following properties and methods have been removed to tidy things up:

  • The Camera.renderToTexture property has been removed. Effects are now handled via pipelines.
  • The Camera.renderToGame property has been removed. Effects are now handled via pipelines.
  • The Camera.canvas property has been removed. Textures are handled by pipelines.
  • The Camera.context property has been removed. Textures are handled by pipelines.
  • The Camera.glTexture property has been removed. GL Textures are handled by pipelines.
  • The Camera.framebuffer property has been removed. GL Framebuffers are handled by pipelines.
  • The Camera.setRenderToTexture method has been removed. Effects are now handled via pipelines.
  • The Camera.clearRenderToTexture method has been removed. Effects are now handled via pipelines.

These changes mean that you can no longer render a Camera to a canvas in Canvas games.

Other changes and fixes:

  • Camera.zoomX is a new property that allows you to specifically set the horizontal zoom factor of a Camera.
  • Camera.zoomY is a new property that allows you to specifically set the vertical zoom factor of a Camera.
  • The Camera.setZoom method now allows you to pass two parameters: x and y, to control the zoomX and zoomY values accordingly.
  • The Camera.zoom property now returns an average of the zoomX and zoomY properties.
  • Cameras.Scene2D.Events.FOLLOW_UPDATE is a new Event that is dispatched by a Camera when it is following a Game Object. It is dispatched every frame, right after the final Camera position and internal matrices have been updated. Use it if you need to react to a camera, using its most current position and the camera is following something. Fix #5253 (thanks @rexrainbow)
  • If the Camera has roundPixels set it will now round the internal scroll factors and worldView during the preRender step. Fix #4464 (thanks @Antriel)

Spine Plugin - New Features, API Changes and Bug Fixes

  • The Spine Runtimes have been updated to 3.8.99, which are the most recent non-beta versions. Please note, you will need to re-export your animations if you're working in a version of Spine lower than 3.8.20. We do not impose this requirement, the Spine editor does.
  • SpineContainer is a new Game Object available via this.add.spineContainer to which you can add Spine Game Objects only. It uses a special rendering function to retain batching, even across multiple container or Spine Game Object instances, resulting in dramatically improved performance compared to using regular Containers. You can still use regular Containers if you need, but they do not benefit from the new batching.
  • A Spine Game Object with setVisible(false) will no longer still cause internal gl commands and is now properly skipped, retaining any current batch in the process. Fix #5174 (thanks @Kitsee)
  • The Spine Game Object WebGL Renderer will no longer clear the type if invisible and will only end the batch if the next type doesn't match.
  • The Spine Game Object WebGL Renderer will no longer rebind the pipeline if it was the final object on the display list, saving lots of gl commands.
  • The Webpack build scripts have all been updated for Webpack 4.44.x. Fix #5243 (thanks @RollinSafary)
  • There is a new npm script npm run plugin.spine.runtimes which will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo into plugins/spine/ in order for this to work and then run npm i.
  • Spine Game Objects can now be rendered to Render Textures. Fix #5184 (thanks @Kitsee)
  • Using > 128 Spine objects in a Container would cause a WebGL: INVALID_OPERATION: vertexAttribPointer: no ARRAY_BUFFER is bound and offset is non-zero error if you added any subsequent Spine objects to the Scene. There is now no limit. Fix #5246 (thanks @d7561985)
  • The Spine Plugin will now work in HEADLESS mode without crashing. Fix #4988 (thanks @raimon-segura)
  • Spine Game Objects now use -1 as their default blend mode, which means 'skip setting it', as blend modes should be handled by the Spine skeletons directly.
  • The Spine TypeScript defs have been updated for the latest version of the plugin and to add SpineContainers.
  • The SpineGameObject.setAnimation method will now use the trackIndex parameter if ignoreIfPlaying is set and run the check against this track index. Fix #4842 (thanks @vinerz)
  • The SpineFile will no longer throw a warning if adding a texture into the Texture Manager that already exists. This allows you to have multiple Spine JSON use the same texture file, however, it also means you now get no warning if you accidentally load a texture that exists, so be careful with your keys! Fix #4947 (thanks @Nomy1)
  • The Spine Plugin destroy method will now no longer remove the Game Objects from the Game Object Factory, or dispose of the Scene Renderer. This means when a Scene is destroyed, it will keep the Game Objects in the factory for other Scenes to use. Fix #5279 (thanks @Racoonacoon)
  • SpinePlugin.gameDestroy is a new method that is called if the Game instance emits a destroy event. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.
  • SpineFile will now check to see if another identical atlas in the load queue is already loading the texture it needs and will no longer get locked waiting for a file that will never complete. This allows multiple skeleton JSONs to use the same atlas data. Fix #5331 (thanks @Racoonacoon)
  • SpineFile now uses a ! character to split the keys, instead of an underscore, preventing the plugin from incorrectly working out the keys for filenames with underscores in them. Fix #5336 (thanks @Racoonacoon)
  • SpineGameObject.willRender is no longer hard-coded to return true. It instead now takes a Camera parameter and performs all of the checks needed before returning. Previously, this happened during the render functions.
  • The Spine Plugin now uses a single instance of the Scene Renderer when running under WebGL. All instances of the plugin (installed per Scene) share the same base Scene Renderer, avoiding duplicate allocations and resizing events under multi-Scene games. Fix #5286 (thanks @spayton BunBunBun)

Game Objects - New Features, API Changes and Bug Fixes

Lots of the core Phaser Game Objects have been improved in 3.50 and there are several new Game Objects as well.

Render Texture Game Object

The Render Texture Game Object has been rewritten to use the new RenderTarget class internally, rather than managing its own framebuffer and gl textures directly. The core draw methods are now a lot simpler and no longer require manipulating render pipelines.

As a result of these changes the following updates have happened:

  • RenderTexture.renderTarget is a new property that contains a RenderTarget instance, which is used for all drawing.
  • The RenderTexture.framebuffer property has been removed. You can now access this via RenderTexture.renderTarget.framebuffer.
  • The RenderTexture.glTexture property has been removed. You can now access this via RenderTexture.renderTarget.texture.
  • The RenderTexture.gl property has been removed.

Render Textures have the following new features:

  • RenderTexture.beginDraw is a new method that allows you to create a batched draw to the Render Texture. Use this method to begin the batch.
  • RenderTexture.batchDraw is a new method that allows you to batch the drawing of an object to the Render Texture. You should never call this method unless you have previously started a batch with beginDraw. You can call this method as many times as you like, to draw as many objects as you like, without causing a framebuffer bind.
  • RenderTexture.batchDrawFrame is a new method that allows you to batch the drawing of a texture frame to the Render Texture. You should never call this method unless you have previously started a batch with beginDraw. You can call this method as many times as you like, to draw as many frames as you like, without causing a framebuffer bind.
  • RenderTexture.endDraw is a new method that ends a previously created batched draw on the Render Texture. Use it to write all of your batch changes to the Render Texture.
  • You can now draw a Group to a RenderTexture. Previously, it failed to pass the camera across, resulting in none of the Group children being drawn. Fix #5330 (thanks @somnolik)

Render Textures have the following bug fixes:

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • RenderTexture.erase has never worked when using the Canvas Renderer and a texture frame, only with Game Objects. It now works with both. Fix #5422 (thanks @vforsh)

Point Lights Game Object

The Point Light Game Object is brand new in 3.50 and 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 radial 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 calculations. 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 display 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 PointLight Game Object has the following unique properties and methods:

  • The PointLight.color property is an instance of the Color object that controls the color value of the light.
  • The PointLight.intensity property sets the intensity of the light. The colors of the light are multiplied by this value during rendering.
  • The PointLight.attenuation property sets the attenuation of the light, which is the force with which the light falls off from its center.
  • The PointLight.radius property sets the radius of the light, in pixels. This value is also used for culling.

Point Lights also have corresponding Factory and Creator functions, available from within a Scene:

js this.add.pointlight(x, y, color, radius, intensity, attenuation);

and

js this.make.pointlight({ x, y, color, radius, intensity, attenuation });

Mesh Game Object

The Mesh Game Object has been rewritten from scratch in v3.50 with a lot of changes to make it much more useful. It is accompanied by the new Geom.Mesh set of functions.

  • Geom.Mesh is a new namespace that contains the Mesh related geometry functions. These are stand-alone functions that you may, or may not require, depending on your game.
  • Geom.Mesh.Vertex is a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.
  • Geom.Mesh.Face is a new class that consists of references to the three Vertex instances that construct a single Face in a Mesh and provides methods for manipulating them.
  • Geom.Mesh.GenerateVerts is a new function that will return an array of Vertex and Face objects generated from the given data. You can provide index, or non-index vertex lists, along with UV data, normals, colors and alpha which it will parse and return the results from.
  • Geom.Mesh.GenerateGridVerts is a new function that will generate a series of Vertex objects in a grid format, based on the given GenerateGridConfig config file. You can set the size of the grid, the number of segments to split it into, translate it, color it and tile the texture across it. The resulting data can be easily used by a Mesh Game Object.
  • Geom.Mesh.GenerateObjVerts is a new function that will generate a series of Vertex objects based on the given parsed Wavefront Obj Model data. You can optionally scale and translate the generated vertices and add them to a Mesh.
  • Geom.Mesh.ParseObj is a new function that will parse a triangulated Wavefront OBJ file into model data into a format that the GenerateObjVerts function can consume.
  • Geom.Mesh.ParseObjMaterial is a new function that will parse a Wavefront material file and extract the diffuse color data from it, combining it with the parsed object data.
  • Geom.Mesh.RotateFace is a new function that will rotate a Face by a given amount, based on an optional center of rotation.
  • Loader.OBJFile is a new File Loader type that can load triangulated Wavefront OBJ files, and optionally material files, which are then parsed and stored in the OBJ Cache.
  • The Mesh constructor and MeshFactory signatures have changed to scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first. indicies is a new parameter that allows you to provide indexed vertex data to create the Mesh from, where the indicies array holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. The indicies array is optional. If your data is not indexed, then simply pass null or an empty array for this parameter.
  • The Mesh Game Object now has the Animation State Component. This allows you to create and play animations across the texture of a Mesh, something that previously wasn't possible. As a result, the Mesh now adds itself to the Update List when added to a Scene.
  • Mesh.addVertices is a new method that allows you to add vertices to a Mesh Game Object based on the given parameters. This allows you to modify a mesh post-creation, or populate it with data at a later stage.
  • Mesh.addVerticesFromObj is a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the new OBJFile with a this.load.obj call, then you can use the key with this method. This method also takes an optional scale and position parameters to control placement of the created model within the Mesh.
  • Mesh.hideCCW is a new boolean property that, when enabled, tells a Face to not render if it isn't counter-clockwise. You can use this to hide backward facing Faces.
  • Mesh.modelPosition is a new Vector3 property that allows you to translate the position of all vertices in the Mesh.
  • Mesh.modelRotation is a new Vector3 property that allows you to rotate all vertices in the Mesh.
  • Mesh.modelScale is a new Vector3 property that allows you to scale all vertices in the Mesh.
  • Mesh.panX is a new function that will translate the view position of the Mesh on the x axis.
  • Mesh.panY is a new function that will translate the view position of the Mesh on the y axis.
  • Mesh.panZ is a new function that will translate the view position of the Mesh on the z axis.
  • Mesh.setPerspective is a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.
  • Mesh.setOrtho is a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.
  • Mesh.clear is a new method that will destroy all Faces and Vertices and clear the Mesh.
  • Mesh.depthSort is a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.
  • Mesh.addVertex is a new method that allows you to add a new single Vertex into the Mesh.
  • Mesh.addFace is a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.
  • Mesh.getFaceCount new is a new method that will return the total number of Faces in the Mesh.
  • Mesh.getVertexCount new is a new method that will return the total number of Vertices in the Mesh.
  • Mesh.getFace new is a new method that will return a Face instance from the Mesh based on the given index.
  • Mesh.getFaceAt new is a new method that will return an array of Face instances from the Mesh based on the given position. The position is checked against each Face, translated through the optional Camera and Mesh matrix. If more than one Face intersects, they will all be returned but the array will be depth sorted first, so the first element will be that closest to the camera.
  • Mesh.vertices is now an array of GameObject.Vertex instances, not a Float32Array.
  • Mesh.faces is a new array of GameObject.Face instances, which is populated during a call to methods like addVertices or addModel.
  • Mesh.totalRendered is a new property that holds the total number of Faces that were rendered in the previous frame.
  • Mesh.setDebug is a new method that allows you to render a debug visualization of the Mesh vertices to a Graphics Game Object. You can provide your own Graphics instance and optionally callback that is invoked during rendering. This allows you to easily visualize the vertices of your Mesh to help debug UV mapping.
  • The Mesh now renders by iterating through the Faces array, not the vertices. This allows you to use Array methods such as BringToTop to reposition a Face, thus changing the drawing order without having to repopulate all of the vertices. Or, for a 3D model, you can now depth sort the Faces.
  • The Mesh Game Object now extends the SingleAlpha component and the alpha value is factored into the final alpha value per vertex during rendering. This means you can now set the whole alpha across the Mesh using the standard setAlpha methods. But, if you wish to, you can still control the alpha on a per-vertex basis as well.
  • The Mesh renderer will now check to see if the pipeline capacity has been exceeded for every Face added, allowing you to use Meshes with vertex counts that exceed the pipeline capacity without causing runtime errors.
  • You can now supply just a single numerical value as the colors parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the color for all vertices created.
  • You can now supply just a single numerical value as the alphas parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the alpha for all vertices created.
  • Mesh.debugGraphic is a new property that holds the debug Graphics instance reference.
  • Mesh.debugCallback is a new property that holds the debug render callback.
  • Mesh.renderDebugVerts is a new method that acts as the default render callback for setDebug if none is provided.
  • Mesh.preDestroy is a new method that will clean-up the Mesh arrays and debug references on destruction.
  • Mesh.isDirty is a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically in preUpdate to avoid generating lots of math when nothing has changed.
  • The Mesh.uv array has been removed. All UV data is now bound in the Vertex instances.
  • The Mesh.colors array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.alphas array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.tintFill property is now a boolean and defaults to false.

Layer Game Object

A Layer is a special type of Game Object that acts as a Display List. You can add any type of Game Object to a Layer, just as you would to a Scene. Layers can be used to visually group together 'layers' of Game Objects:

```javascript const spaceman = this.add.sprite(150, 300, 'spaceman'); const bunny = this.add.sprite(400, 300, 'bunny'); const elephant = this.add.sprite(650, 300, 'elephant');

const layer = this.add.layer();

layer.add([ spaceman, bunny, elephant ]); ```

The 3 sprites in the example above will now be managed by the Layer they were added to. Therefore, if you then set layer.setVisible(false) they would all vanish from the display.

You can also control the depth of the Game Objects within the Layer. For example, calling the setDepth method of a child of a Layer will allow you to adjust the depth of that child within the Layer itself, rather than the whole Scene. The Layer, too, can have its depth set as well.

The Layer class also offers many different methods for manipulating the list, such as the methods moveUp, moveDown, sendToBack, bringToTop and so on. These allow you to change the display list position of the Layers children, causing it to adjust the order in which they are rendered. Using setDepth on a child allows you to override this.

Layers can have Post FX Pipelines set, which allows you to easily enable a post pipeline across a whole range of children, which, depending on the effect, can often be far more efficient that doing so on a per-child basis.

Layers have no position or size within the Scene. This means you cannot enable a Layer for physics or input, or change the position, rotation or scale of a Layer. They also have no scroll factor, texture, tint, origin, crop or bounds.

If you need those kind of features then you should use a Container instead. Containers can be added to Layers, but Layers cannot be added to Containers.

However, you can set the Alpha, Blend Mode, Depth, Mask and Visible state of a Layer. These settings will impact all children being rendered by the Layer.

BitmapText Game Object

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has to work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.
  • You can now use setMaxWidth on DynamicBitmapText, which wasn't previously possible. Fix #4997 (thanks @AndreaBoeAbrahamsen)

Quad Game Object Removed

The Quad Game Object has been removed from v3.50.0.

You can now create your own Quads easily using the new Geom.Mesh.GenerateGridVerts function, which is far more flexible than the old quads were.

Animation API - New Features, API Changes and Bug Fixes

If you use Animations in your game, please read the following important API changes in 3.50:

The Animation API has had a significant overhaul to improve playback handling. Instead of just playing an animation based on its global key, you can now supply a new PlayAnimationConfig object instead, which allows you to override any of the default animation settings, such as duration, delay and yoyo (see below for the full list). This means you no longer have to create lots of duplicate animations just to change properties such as duration, and can now set them dynamically at run-time as well.

  • The Animation class no longer extends EventEmitter, as it no longer emits any events directly. This means you cannot now listen for events directly from an Animation instance. All of the events are now dispatched by the Game Objects instead.
  • All of the SPRITE_ANIMATION_KEY events have been removed. Instead, please use the new events which all carry the frameKey parameter, which can be used to handle frame specific events. The only exception to this is ANIMATION_COMPLETE_KEY, which is a key specific version of the completion event.
  • ANIMATION_UPDATE_EVENT is a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.
  • ANIMATION_STOP_EVENT is a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of the stop methods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)
  • The Game Object Component.Animation component has been renamed to AnimationState and has moved namespace. It's now in Phaser.Animations instead of GameObjects.Components to help differentiate it from the Animation class when browsing the documentation.
  • The play, playReverse, playAfterDelay, playAfterRepeat and chain Sprite and Animation Component methods can now all take a Phaser.Types.Animations.PlayAnimationConfig configuration object, as well as a string, as the key parameter. This allows you to override any default animation setting with those defined in the config, giving you far greater control over animations on a Game Object level, without needing to globally duplicate them.
  • AnimationState.create is a new method that allows you to create animations directly on a Sprite. These are not global and never enter the Animation Manager, instead residing within the Sprite itself. This allows you to use the same keys across both local and global animations and set-up Sprite specific local animations.
  • AnimationState.generateFrameNumbers is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • AnimationState.generateFrameNames is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • All playback methods: play, playReverse, playAfterDelay and playAfterRepeat will now check to see if the given animation key exists locally on the Sprite first. If it does, it's used, otherwise it then checks the global Animation Manager for the key instead.
  • AnimationState.skipMissedFrames is now used when playing an animation, allowing you to create animations that run at frame rates far exceeding the refresh rate, or that will update to the correct frame should the game lag. Feature #4232 (thanks @colorcube)
  • AnimationManager.addMix is a new method that allows you to create mixes 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.
  • AnimationManager.getMix is a new method that will return the mix duration between the two given animations.
  • AnimationManager.removeMix is a new method that will remove the mixture between either two animations, or all mixtures for the given animation.
  • AnimationState.remove is a new method that will remove a locally stored Animation instance from a Sprite.
  • AnimationState.get is a new method that will return a locally stored Animation instance from the Sprite.
  • AnimationState.exists is a new method that will check if a locally stored Animation exists on the Sprite.
  • The internal AnimationState.remove method has been renamed to globalRemove.
  • AnimationState.textureManager is a new property that references the global Texture Manager.
  • AnimationState.anims is a new property that contains locally created Animations in a Custom Map.
  • AnimationState.play and Sprite.play no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • AnimationState.playReverse and Sprite.playReverse no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • The AnimationState.delayedPlay method has been renamed to playAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration.
  • The AnimationState.stopOnRepeat method has been renamed to stopAfterRepeat
  • The AnimationState.getCurrentKey method has been renamed to getName.
  • AnimationState.getFrameName is a new method that will return the key of the current Animation Frame, if an animation has been loaded.
  • AnimationState.playAfterDelay and Sprite.playAfterDelay are new methods that will play the given animation after the delay in ms expires.
  • AnimationState.playAfterRepeat and Sprite.playAfterRepeat are new methods that will play the given animation after the current animation finishes repeating. You can also specify the number of repeats allowed left to run.
  • The AnimationState.chain method is now available on the Sprite class.
  • The AnimationState.stopAfterDelay method is now available on the Sprite class.
  • The AnimationState.stopAfterRepeat method is now available on the Sprite class.
  • The AnimationState.stopOnFrame method is now available on the Sprite class.
  • AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser. Please see the comprehensive documentation for this method for full details on how to do this.
  • AnimationState now handles all of the loading of the animation. It no longer has to make calls out to the Animation Manager or Animation instance itself and will load the animation data directly, replacing as required from the optional PlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.
  • The PlayAnimationConfig.frameRate property lets you optionally override the animation frame rate.
  • The PlayAnimationConfig.duration property lets you optionally override the animation duration.
  • The PlayAnimationConfig.delay property lets you optionally override the animation delay.
  • The PlayAnimationConfig.repeat property lets you optionally override the animation repeat counter.
  • The PlayAnimationConfig.repeatDelay property lets you optionally override the animation repeat delay value.
  • The PlayAnimationConfig.yoyo property lets you optionally override the animation yoyo boolean.
  • The PlayAnimationConfig.showOnStart property lets you optionally override the animation show on start value.
  • The PlayAnimationConfig.hideOnComplete property lets you optionally override the animation hide on complete value.
  • The PlayAnimationConfig.startFrame property lets you optionally set the animation frame to start on.
  • The PlayAnimationConfig.timeScale property lets you optionally set the animation time scale factor.
  • AnimationState.delayCounter is a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animation START events fire. Fix #4426 (thanks @bdaenen)
  • AnimationState.hasStarted is a new boolean property that allows you to tell if the current animation has started playing, or is still waiting for a delay to expire.
  • AnimationState.showOnStart is a new boolean property that controls if the Game Object should have setVisible(true) called on it when the animation starts.
  • AnimationState.hideOnComplete is a new boolean property that controls if the Game Object should have setVisible(false) called on it when the animation completes.
  • The AnimationState.chain method docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does!
  • The AnimationState.setDelay method has been removed. It never actually worked and you can now perform the same thing by calling either playAfterDelay or setting the delay property in the play config.
  • The AnimationState.getDelay method has been removed. You can now read the delay property directly.
  • The AnimationState.setRepeat method has been removed. You can achieve the same thing by setting the repeat property in the play config, or adjusting the public repeatCounter property if the animation has started.
  • AnimationState.handleStart is a new internal private method that handles the animation start process.
  • AnimationState.handleRepeat is a new internal private method that handles the animation repeat process.
  • AnimationState.handleStop is a new internal private method that handles the animation stop process.
  • AnimationState.handleComplete is a new internal private method that handles the animation complete process.
  • AnimationState.emitEvents is a new internal private method that emits animation events, cutting down on duplicate code.
  • The AnimationState.restart method has a new optional boolean parameter resetRepeats which controls if you want to reset the repeat counter during the restart, or not.
  • Animation.getTotalFrames is a new method that will return the total number of frames in the animation. You can access it via this.anims.currentAnim.getTotalFrames from a Sprite.
  • Animation.calculateDuration is a new method that calculates the duration, frameRate and msPerFrame for a given animation target.
  • The BuildGameObjectAnimation function now uses the PlayAnimationConfig object to set the values.
  • Sprite.playReverse is a new method that allows you to play the given animation in reverse on the Sprite.
  • Sprite.playAfterDelay is a new method that allows you to play the given animation on the Sprite after a delay.
  • Sprite.stop is a new method that allows you to stop the current animation on the Sprite.
  • AnimationManager.load has been removed as it's no longer required.
  • AnimationManager.staggerPlay has been fixed so you can now pass in negative stagger values.
  • AnimationManager.staggerPlay has a new optional boolean parameter staggerFirst, which allows you to either include or exclude the first child in the stagger calculations.
  • The Animation.completeAnimation method has been removed as it's no longer required.
  • The Animation.load method has been removed as it's no longer required.
  • The Animation.setFrame method has been removed as it's no longer required.
  • The Animation.getFirstTick method has no longer needs the includeDelay parameter, as it's handled by AnimationState now.
  • The Animation.getFrames method has a new optional boolean parameter sortFrames which will run a numeric sort on the frame names after constructing them, if a string-based frame is given.
  • Types.Animations.Animation has a new boolean property sortFrames, which lets Phaser numerically sort the generated frames.
  • AnimationState.timeScale is a new public property that replaces the old private _timeScale property.
  • AnimationState.delay is a new public property that replaces the old private _delay property.
  • AnimationState.repeat is a new public property that replaces the old private _repeat property.
  • AnimationState.repeatDelay is a new public property that replaces the old private _repeatDelay property.
  • AnimationState.yoyo is a new public property that replaces the old private _yoyo property.
  • AnimationState.inReverse is a new public property that replaces the old private _reverse property.
  • AnimationState.startAnimation is a new public method that replaces the old private _startAnimation method.
  • The AnimationState.getProgress method has been fixed so it will return correctly if the animation is playing in reverse.
  • The AnimationState.globalRemove method will now always be called when an animation is removed from the global Animation Manager, not just once.
  • The AnimationState.getRepeat method has now been removed. You can get the value from the repeat property.
  • The AnimationState.setRepeatDelay method has now been removed. You can set the value using the repeatDelay config property, or changing it at run-time.
  • AnimationState.complete is a new method that handles the completion in animation playback.
  • The AnimationState.setTimeScale method has now been removed. You can set the value using the timeScale config property, or changing it at run-time.
  • The AnimationState.getTimeScale method has now been removed. You can read the value using the timeScale property.
  • The AnimationState.getTotalFrames method has been fixed and won't error if called when no animation is loaded.
  • The AnimationState.setYoyo method has now been removed. You can set the value using the yoyo config property, or changing it at run-time.
  • The AnimationState.getYoyo method has now been removed. You can read the value using the yoyo property.
  • The AnimationState.stopAfterRepeat method now has an optional parameter repeatCount, so you can tell the animation to stop after a specified number of repeats, not just 1.
  • When playing an animation in reverse, if it reached the first frame and had to repeat, it would then jump to the frame before the final frame and carry on, skipping out the final frame.
  • The AnimationState.updateFrame method has now been removed. Everything is handled by setCurrentFrame instead, which removes one extra step out of the update process.
  • GenerateFrameNames will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers would include the __BASE frame by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.
  • GenerateFrameNumbers can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.
  • GenerateFrameNames can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.

Tilemap - New Features, API Changes and Bug Fixes

There are three large changes to Tilemaps in 3.50. If you use tilemaps, you must read this section:

1) The first change is that there are no longer DynamicTilemapLayer and StaticTilemapLayer classes. They have both been removed and replaced with the new TilemapLayer class. This new class consolidates features from both and provides a lot cleaner API experience, as well as speeding up internal logic.

In your game where you use map.createDynamicLayer or map.createStaticLayer replace it with map.createLayer instead.

2) The second change is that the Tilemap system now supports isometric, hexagonal and staggered isometric map types, along with the previous orthogonal format, thanks to a PR from @svipal. You can now export maps using any of these orientations from the Tiled Map Editor and load them into Phaser using the existing tilemap loading API. No further changes need to take place in the way your maps are loaded.

3) The Tilemap.createFromObjects method has been overhauled to make it much more useful. The method signature has changed and it now takes a new CreateFromObjectLayerConfig configuration object, or an array of them, which allows much more fine-grained control over which objects in the Tiled Object Layers are converted and what they are converted to. Previously it could only convert to Sprites, but you can now pass in a custom class, filter based on id, gid or name, even provide a Container to add the created Game Objects to. Please see the new documentation for this method and the config object for more details. Fix #3817 #4613 (thanks @georgzoeller @Secretmapper)

  • The Tilemap.createDynamicLayer method has been renamed to createLayer.
  • The Tilemap.createStaticLayer method has been removed. Use createLayer instead.
  • The Tilemap.createBlankDynamicLayer method has been renamed to createBlankLayer.
  • The Tilemap.convertLayerToStatic method has been removed as it is no longer required.
  • The TilemapLayerWebGLRenderer function will no longer iterate through the layer tilesets, drawing tiles from only that set. Instead all it does now is iterate directly through only the tiles. This allows it to take advantage of the new Multi Texturing pipeline and also draw multi-tileset isometric layers correctly.
  • Phaser.Types.Tilemaps.TilemapOrientationType is a new type def that holds the 4 types of map orientation now supported.
  • The Tile.updatePixelXY method now updates the tile XY position based on map type.
  • ParseTilesets will now correctly handle non-consecutive tile IDs. It also now correctly sets the maxId property, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)
  • Tilemap.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • LayerData.orientation is a new property that holds the tilemap layers orientation constant.
  • LayerData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • MapData.orientation is a new property that holds the tilemap layers orientation constant.
  • MapData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • Tilemaps.Components.HexagonalWorldToTileY is a new function that converts a world Y coordinate to hexagonal tile Y coordinate.
  • Tilemaps.Components.StaggeredWorldToTileY is a new function that converts a world Y coordinate to staggered tile Y coordinate.
  • Tilemaps.Components.HexagonalWorldToTileXY is a new function that converts world coordinates to hexagonal tile coordinates.
  • Tilemaps.Components.IsometricWorldToTileXY is a new function that converts world coordinates to isometric tile coordinates.
  • Tilemaps.Components.StaggeredWorldToTileXY is a new function that converts world coordinates to staggered tile coordinates.
  • Tilemaps.Components.HexagonalTileToWorldY is a new function that converts a hexagonal Y coordinate to a world coordinate.
  • Tilemaps.Components.StaggeredTileToWorldY is a new function that converts a staggered Y coordinate to a world coordinate.
  • Tilemaps.Components.HexagonalTileToWorldXY is a new function that converts hexagonal tile coordinates to world coordinates.
  • Tilemaps.Components.IsometricTileToWorldXY is a new function that converts isometric tile coordinates to world coordinates.
  • Tilemaps.Components.StaggeredTileToWorldXY is a new function that converts staggered tile coordinates to world coordinates.
  • Tilemaps.Components.GetTileToWorldXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldXXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetCullTilesFunction is a new function that returns the correct culling function to use.
  • Tilemaps.Components.HexagonalCullTiles is a new function that culls tiles in a hexagonal map.
  • Tilemaps.Components.StaggeredCullTiles is a new function that culls tiles in a staggered map.
  • Tilemaps.Components.IsometricCullTiles is a new function that culls tiles in a isometric map.
  • Tilemaps.Components.CullBounds is a new function that calculates the cull bounds for an orthogonal map.
  • Tilemaps.Components.HexagonalCullBounds is a new function that calculates the cull bounds for a hexagonal map.
  • Tilemaps.Components.StaggeredCullBounds is a new function that calculates the cull bounds for a staggered map.
  • Tilemaps.Components.RunCull is a new function that runs the culling process from the combined bounds and tilemap.
  • Tilemap._convert is a new internal private hash of tilemap conversion functions used by the public API.
  • The Tilemap._isStaticCall method has been removed and no Tilemap methods now check this, leading to faster execution.
  • The Arcade Physics Sprites vs. Tilemap Layers flow has changed. Previously, it would iterate through a whole bunch of linked functions, taking lots of jumps in the process. It now just calls the GetTilesWithinWorldXY component directly, saving lots of overhead.
  • The method Tilemap.weightedRandomize has changed so that the parameter weightedIndexes is now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional.
  • The method TilemapLayer.weightedRandomize has changed so that the parameter weightedIndexes is now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional.

Update List - New Features, API Changes and Bug Fixes

The way in which Game Objects add themselves to the Scene Update List has changed. Instead of being added by the Factory methods, they will now add and remove themselves based on the new ADDED_TO_SCENE and REMOVED_FROM_SCENE events. This means, you can now add Sprites directly to a Container, or Group, and they'll animate properly without first having to be part of the Update List. The full set of changes and new features relating to this follow:

  • GameObjects.Events.ADDED_TO_SCENE is a new event, emitted by a Game Object, when it is added to a Scene, or a Container that is part of the Scene.
  • GameObjects.Events.REMOVED_FROM_SCENE is a new event, emitted by a Game Object, when it is removed from a Scene, or a Container that is part of the Scene.
  • Scenes.Events.ADDED_TO_SCENE is a new event, emitted by a Scene, when a new Game Object is added to the display list in the Scene, or a Container that is on the display list.
  • Scenes.Events.REMOVED_FROM_SCENE is a new event, emitted by a Scene, when it a Game Object is removed from the display list in the Scene, or a Container that is on the display list.
  • GameObject.addedToScene is a new method that custom Game Objects can use to perform additional set-up when a Game Object is added to a Scene. For example, Sprite uses this to add itself to the Update List.
  • GameObject.removedFromScene is a new method that custom Game Objects can use to perform additional tear-down when a Game Object is removed from a Scene. For example, Sprite uses this to remove themselves from the Update List.
  • Game Objects no longer automatically remove themselves from the Update List during preDestroy. This should be handled directly in the removedFromScene method now.
  • The Container will now test to see if any Game Object added to it is already on the display list, or not, and emit its ADDED and REMOVED events accordingly. Fix #5267 #3876 (thanks @halgorithm @mbpictures)
  • DisplayList.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • DisplayList.addChildCallback is a new method that overrides the List callback and fires the new ADDED events.
  • DisplayList.removeChildCallback is a new method that overrides the List callback and fires the new REMOVED events.
  • GameObjectCreator.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • GameObjectFactory.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • ProcessQueue.checkQueue is a new boolean property that will make sure only unique objects are added to the Process Queue.
  • The Update List now uses the new checkQueue property to ensure no duplicate objects are on the active list.
  • DOMElementFactory, ExternFactory, ParticleManagerFactor, RopeFactory and SpriteFactory all no longer add the objects to the Update List, this is now handled by the ADDED events instead.
  • Sprite, Rope, ParticleEmitterManager, Extern and DOMElement now all override the addedToScene and removedFromScene callbacks to handle further set-up tasks.

Input Manager and Mouse Manager - New Features, API Changes and Bug Fixes

  • ScaleManager.refresh is now called when the Game.READY event fires. This fixes a bug where the Scale Manager would have the incorrect canvas bounds, because they were calculated before a previous canvas was removed from the DOM. Fix #4862 (thanks @dranitski)
  • The Game Config property inputMouseCapture has been removed, as this is now split into 3 new config options:
  • inputMousePreventDefaultDown is a new config option that allows you to control preventDefault calls specifically on mouse down events. Set it via input.mouse.preventDefaultDown in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultUp is a new config option that allows you to control preventDefault calls specifically on mouse up events. Set it via input.mouse.preventDefaultUp in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultMove is a new config option that allows you to control preventDefault calls specifically on mouse move events. Set it via input.mouse.preventDefaultMove in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultWheel is a new config option that allows you to control preventDefault calls specifically on mouse wheel events. Set it via input.mouse.preventDefaultWheel in the Game Config. It defaults to true, the same as the previous capture property did.
  • The MouseManager.capture property has been removed, as this is now split into 3 new config options (see below)
  • MouseManager.preventDefaultDown is a new boolean property, set via the inputMousePreventDefaultDown config option that allows you to toggle capture of mouse down events at runtime.
  • MouseManager.preventDefaultUp is a new boolean property, set via the inputMousePreventDefaultUp config option that allows you to toggle capture of mouse up events at runtime.
  • MouseManager.preventDefaultMove is a new boolean property, set via the inputMousePreventDefaultMove config option that allows you to toggle capture of mouse move events at runtime.
  • MouseManager.preventDefaultWheel is a new boolean property, set via the inputMousePreventDefaultWheel config option that allows you to toggle capture of mouse wheel at runtime.
  • In the MouseManager the up, down and move events are no longer set as being passive if captured. Over, Out, Wheel and the Window level Down and Up events are always flagged as being passive. Wheel events are non-passive if capturing is enabled.
  • The GamepadPlugin will now call refreshPads as part of its start process. This allows you to use Gamepads across multiple Scenes, without having to wait for a connected event from each one of them. If you've already had a connected event in a previous Scene, you can now just read the pads directly via this.input.gamepad.pad1 and similar. Fix #4890 (thanks @Sytten)
  • Shutting down the Gamepad plugin (such as when sleeping a Scene) no longer calls GamepadPlugin.disconnectAll, but destroying it does.
  • Gamepad._created is a new private internal property that keeps track of when the instance was created. This is compared to the navigator timestamp in the update loop to avoid event spamming. Fix #4890.
  • Pointer.down will now check if the browser is running under macOS and if the ctrl key was also pressed, if so, it will flag the down event as being a right-click instead of a left-click, as per macOS conventions. Fix #4245 (thanks @BigZaphod)
  • When destroying an interactive Game Object that had useHandCursor enabled, it would reset the CSS cursor to default, even if the cursor wasn't over that Game Object. It will now only reset the cursor if it's over the Game Object being destroyed. Fix #5321 (thanks @JstnPwll)
  • The InputPlugin.shutdown method will now reset the CSS cursor, in case it was set by any Game Objects in the Scene that have since been destroyed.
  • The InputPlugin.processOverEvents has had a duplicate internal loop removed from it (thanks KingCosmic)

Tint Component Updates and resulting Shader Changes

Phaser has had the ability to apply an additive tint to a Game Object since the beginning, and gained 'filled tints', with and without texture alpha, in v3.11. While this was handy, it introduced a 3-way if-else condition to the shaders to handle the different modes. Plus, setting tint colors was also generating rgb order Float32 color values for each Game Object, making reading those colors back again difficult (as they'd return in BGR order).

This has all changed in 3.50, as outlined below. Tint values are now used directly in the shader and don't pass through a color conversion function first. Lots of private properties have been removed and the shaders no longer have a 3-way if-else block. All of this means improved performance and a slight reduction in memory overhead.

  • Tint.tintTopLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTL which has now been removed.
  • Tint.tintTopRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTR which has now been removed.
  • Tint.tintBottomLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBL which has now been removed.
  • Tint.tintBottomRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBR which has now been removed.
  • The property Tint._isTinted has been removed as it's no longer required.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they now read the color value as outTint.bgr instead of outTint.rgb. This allows the colors to remain in RGB order within the Tint component.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they no longer have a 3-way check on the outTintEffect value.
  • The Multi Pipeline, Bitmap Text, Render Texture, Text, TileSprite and Camera now all read the tint values from the public properties instead of the private _tintTL etc ones. They also now set the tintEffect value directly from the tintFill property, removing another conditional check.
  • The function GetColorFromValue has been removed as it's no longer used internally.
  • The Rope.tintFill property is now a boolean, not an integer, and can no longer take 2 as a value for a complete fill. Instead, you should provide a solid color texture with no alpha.
  • As a result of the change to the shader, all uses of the WebGL Util function getTintAppendFloatAlphaAndSwap have been replaced with getTintAppendFloatAlpha instead.
  • As a result of the change to the shader, the Multi Pipeline now uses the WebGLRenderer.whiteTexture and tintEffect mode of 1 by default, instead of mode 2 (which has been removed) and a transparent texture. This ensures Graphics and Shapes objects still render correctly under the new smaller shader code.
  • WebGLRenderer.whiteTexture is a new property that is a reference to a pure white 4x4 texture that is created during Boot by the Texture Manager. The Graphics Pipeline uses this internally for all geometry fill rendering.
  • The TextureManager now generates a new texture with the key __WHITE during its boot process. This is a pure white 4x4 texture used by the Graphics pipelines.
  • Config.images.white is a new Game Config property that specifies the 4x4 white PNG texture used by Graphics rendering. You can override this via the config, but only do so if needed.

Arcade Physics - New Features, API Changes and Bug Fixes

Prior to v3.50 an Arcade Physics Body could be one of two states: immovable, or movable. An immovable body could not receive any impact from another Body. If something collided with it, it wouldn't even separate to break free from the collision (the other body had to take the full separation value). It was intended for objects such as platforms, ground or walls, there they absolutely shouldn't move under any circumstances. As a result, two immovable bodies could never be collided together. While this worked for scenery-like items, it didn't work if you required maybe 2 players who could collide with each other, but should never be able to push one another. As of 3.50 all physics bodies now have a new property pushable that allows this. A pushable body can share separation with its collider, as well as take on mass-based velocity from the impact. A non-pushable body will behave differently depending on what it collides with. For example, a pushable body hitting a non-pushable (or immovable) body will rebound off it.

  • The Arcade Physics Body class has a new boolean property pushable (true, by default). This allows you to set if a Body can be physically pushed by another Body, or not. Fix #4175 #4415 (thanks @inmylo @CipSoft-Components)
  • Body.setPushable is a new chainable method that allows you to set the pushable state of a Body.
  • Arcade.Components.Pushable is a new component, inherited by the standard Arcade Physics Image and Sprite classes.
  • Bodies will now check to see if they are blocked in the direction they're being pushed, before resolving the collision. This helps stop some bodies from being pushed into other objects.
  • Bodies will now check which direction they were moving and separate accordingly. This helps stop some bodies from being pushed into other objects.
  • ArcadePhysics.disableUpdate is a new method that will prevent the Arcade Physics World update method from being called when the Scene updates. By disabling it, you're free to call the update method yourself, passing in your own delta and time values.
  • ArcadePhysics.enableUpdate is a new method that will make the Arcade Physics World update in time with the Scene update. This is the default, so only call this if you have specifically disabled it previously.
  • ArcadeWorldConfig.customUpdate is a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. If true the World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)
  • Physics.Arcade.Body.setCollideWorldBounds now has a new optional parameter onWorldBounds which allows you to enable the Body's onWorldBounds property in the same call (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityX is a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityY is a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)
  • The PhysicsGroup config now has two new optional properties maxVelocityX and maxVelocityY which allows you to set the maximum velocity on bodies added to the Group (thanks @samme)
  • The Arcade.Body.resetFlags method has a new optional boolean parameter clear. If set, it clears the wasTouching flags on the Body. This happens automatically when Body.reset is called. Previous to this, the flags were not reset until the next physics step (thanks @samme)
  • Physics.Arcade.ProcessX is a new set of functions, called by the SeparateX function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Physics.Arcade.ProcessY is a new set of functions, called by the SeparateY function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Arcade.Body.center values were incorrect after collisions with the world bounds or (for rectangular bodies) after collisions with another body. The body center is now updated after those separations (thanks @samme)
  • The Arcade Physics WORLD_STEP event now has a new parameter: the delta argument (thanks @samme)
  • The Arcade Body drag property has been redefined when damping is used and scales the damping multiplier by the physics step delta. Drag is now the velocity retained after 1 second instead of after 1 step, when damping is used. This makes damping consistent for different physics step rates and more accurate when fixedStep is off. If you use drag you will need to change any existing drag values to get the same effects as before. Convert drag to drag ^ 60 or drag ^ fps if you use a different step rate (thanks @samme)

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.
  • You can now use this.renderer from within a Scene, as it's now a Scene-level property and part of the Injection Map.
  • Clock.addEvent can now take an existing TimerEvent object, as well as a config object. If a TimerEvent is given it will be removed from the Clock, reset and then added. This allows you to pool TimerEvents rather than constantly create and delete them. Fix #4115 (thanks @jcyuan)
  • Clock.removeEvent is a new method that allows you to remove a TimerEvent, or an array of them, from all internal lists of the current Clock.
  • Group.getMatching is a new method that will return any members of the Group that match the given criteria, such as getMatching('visible', true) (thanks @atursams)
  • Utils.Array.SortByDigits is a new function that takes the given array of strings and runs a numeric sort on it, ignoring any non-digits.
  • GroupCreateConfig, which is used when calling Group.createMultiple or Group.createFromConfig, can now accept the following new properties: setOrigin: { x, y, stepX, stepY } which are applied to the items created by the Group.
  • Transform.copyPosition is a new method that will copy the position from the given object to the Game Object (thanks @samme)
  • The Text.MeasureText function, which is used to calculate the ascent and descent of Text Game Objects whenever the style, or font size, is changed, has been updated to use the new actualBoundingBoxAscent functions present in modern browsers. This allows for significantly faster ascent calculations than previously. Older browsers, such as IE, will still fall back (thanks @rexrainbow)
  • GameObjects.GetCalcMatrix is a new function that is used to calculate the transformed Game Object matrix, based on the given Game Object, Camera and Parent. This function is now used by the following Game Objects: BitmapText (Static and Dynamic), Graphics, Extern, Mesh, Rope, Shader, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. This dramatically reduces the amount of duplicate code across the API.
  • Utils.Array.Matrix.Translate is a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.
  • Vertor3.addScale is a new method that will add the given vector and multiply it in the process.
  • When defining the ease used with a Particle Emitter you can now set easeParams in the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh)
  • BitmapMask.createMask is a new method that will internally create the WebGL textures and framebuffers required for the mask. This is now used by the constructor and if the context is lost. It now also clears any previous textures/fbos that may have been created first, helping prevent memory leaks.
  • BitmapMask.clearMask will delete any WebGL textures or framebuffers the mask is using. This is now called when the mask is destroyed, or a new mask is created upon it.
  • Quaternion now has a new property onChangeCallback which, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.
  • The Quaternion.set method has a new optional boolean parameter update (defaults to true), which will call the onChangeCallback if set.
  • Quaternion.setFromEuler is a new method that will set the quaternion from the given Euler object, optionally calling the onChangeCallback in the process.
  • Quaternion.setFromRotationMatrix is a new method that will set the rotation of the quaternion from the given Matrix4.
  • Vector3.setFromMatrixPosition is a new method that will set the components of the Vector3 based on the position of the given Matrix4.
  • Vector3.setFromMatrixColumn is a new method that will set the components of the Vector3 based on the specified Matrix4 column.
  • Vector3.fromArray is a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.
  • Vector3.min is a new method that will set the components of the Vector3 based on the Main.min between it and the given Vector3.
  • Vector3.max is a new method that will set the components of the Vector3 based on the Main.max between it and the given Vector3.
  • Vector3.addVectors is a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.
  • Vector3.addScalar is a new method that will multiply the components of the Vector3 by the scale value given.
  • Vector3.applyMatrix3 is a new method that will take a Matrix3 and apply it to the Vector3.
  • Vector3.applyMatrix4 is a new method that will take a Matrix4 and apply it to the Vector3.
  • Vector3.projectViewMatrix is a new method that multiplies the Vector3 by the given view and projection matrices.
  • Vector3.unprojectViewMatrix is a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.
  • Matrix4.setValues is a new method that allows you to set all of the matrix components individually. Most internal methods now use this.
  • Matrix.multiplyToMat4 is a new method that multiplies a Matrix4 by the given src Matrix4 and stores the results in the out Matrix4.
  • Matrix4.fromRotationXYTranslation is a new method that takes the rotation and position vectors and builds this Matrix4 from them.
  • Matrix4.getMaxScaleOnAxis is a new method that will return the maximum axis scale from the Matrix4.
  • Matrix4.lookAtRH is a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.
  • Matrix4.transform is a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.
  • Matrix4.multiplyMatrices is a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.
  • Matrix4.premultiply is a new method that takes a Matrix4 and multiplies it by the current Matrix4.
  • Matrix4.getInverse is a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.
  • CameraManager.getVisibleChildren is a new method that is called internally by the CameraManager.render method. It filters the DisplayList, so that Game Objects that pass the willRender test for the given Camera are added to a sub-list, which is then passed to the renderer. This avoids the renderer having to do any checks on the children, it just renders each one in turn.
  • Physics.Arcade.Body.setDamping is a new method that allows you to set the useDamping property of a Body in a chainable way. Fix #5352 (thanks @juanitogan)
  • The GameObjects.Graphics.fillGradientStyle method can now accept a different alpha value for each of the fill colors. The default is still 1. If you only provide a single alpha, it'll be used for all colors. Fix #5044 (thanks @zhangciwu)
  • Types.Core.PipelineConfig is a new configuration object that you can set in the Game Config under the pipeline property. It allows you to define custom WebGL pipelines as part of the Game Config, so they're automatically installed and ready for use by all Scenes in your game. You can either set the pipeline object, or set it under the render sub-config.
  • Utils.Object.DeepCopy is a new function that will recursively deep copy an array of object.
  • Time.TimerEvent.getRemaining is a new method that returns the time interval until the next iteration of the Timer Event (thanks @samme)
  • Time.TimerEvent.getRemainingSeconds is a new method that returns the time interval until the next iteration of the Timer Event in seconds (thanks @samme)
  • Time.TimerEvent.getOverallRemaining is a new method that returns the time interval until the last iteration of the Timer Event (thanks @samme)
  • Time.TimerEvent.getOverallRemainingSeconds is a new method that returns the time interval until the last iteration of the Timer Event in seconds (thanks @samme)
  • GameObjects.Video.loadMediaStream is a new method that allows you to hook a Video Game Object up to a Media Stream, rather than a URL, allowing you to stream video from a source such as a webcam (thanks @pirateksh)
  • Display.Color.ColorSpectrum is a new function that will return an array of 1024 Color Object elements aligned in a Color Spectrum layout, where the darkest colors have been omitted.
  • AsepriteFile is a new File Type for the Loader that allows you to load Aseprite images and animation data for use with the new Aseprite animation features. You can call this via this.load.asesprite(png, json).
  • GameObject.displayList is a new property that contains a reference to the Display List to which the Game Object has been added. This will typically either by the Display List owned by a Scene, or a Layer Game Object. You should treat this property as read-only.
  • The Shader Game Object now supports being able to use a Render Texture as a sampler2D texture on the shader #5423 (thanks @ccaleb)
  • BaseSound.pan, HTMLAudioSound.pan and WebAudioSound.pan are new properties that allow you to get or set the pan value of a sound, a value between -1 (full left pan) and 1 (full right pan). Note that pan only works under Web Audio, but the property and event still exists under HTML5 Audio for compatibility (thanks @pi-kei)
  • WebAudioSound.setPan is a new method that allows you to set the pan of the sound. A value between -1 (full left pan) and 1 (full right pan) (thanks @pi-kei)
  • Sound.Events.PAN is a new event dispatched by both Web Audio and HTML5 Audio Sound objects when their pan changes (thanks @pi-kei)

ColorMatrix

  • Phaser.Display.ColorMatrix is a new class that allows you to create and manipulate a 5x4 color matrix, which can be used by shaders or graphics operations.
  • The ColorMatrix.set method allows you to set the values of a ColorMatrix.
  • The ColorMatrix.reset method will reset the ColorMatrix to its default values.
  • The ColorMatrix.getData method will return the data in the ColorMatrix as a Float32Array, useful for setting in a shader uniform.
  • The ColorMatrix.brightness method lets you set the brightness of the ColorMatrix.
  • The ColorMatrix.saturate method lets you set the saturation of the ColorMatrix.
  • The ColorMatrix.desaturate method lets you desaturate the colors in the ColorMatrix.
  • The ColorMatrix.hue method lets you rotate the hues of the ColorMatrix by the given amount.
  • The ColorMatrix.grayscale method converts the ColorMatrix to grayscale.
  • The ColorMatrix.blackWhite method converts the ColorMatrix to black and whites.
  • The ColorMatrix.contrast method lets you set the contrast of the ColorMatrix.
  • The ColorMatrix.negative method converts the ColorMatrix to negative values.
  • The ColorMatrix.desaturateLuminance method applies a desaturated luminance to the ColorMatrix.
  • The ColorMatrix.sepia method applies a sepia tone to the ColorMatrix.
  • The ColorMatrix.night method applies a night time effect to the ColorMatrix.
  • The ColorMatrix.lsd method applies a trippy color effect to the ColorMatrix.
  • The ColorMatrix.brown method applies a brown tone to the ColorMatrix.
  • The ColorMatrix.vintagePinhole method applies a vintage pinhole color effect to the ColorMatrix.
  • The ColorMatrix.kodachrome method applies a kodachrome color effect to the ColorMatrix.
  • The ColorMatrix.technicolor method applies a technicolor color effect to the ColorMatrix.
  • The ColorMatrix.polaroid method applies a polaroid color effect to the ColorMatrix.
  • The ColorMatrix.shiftToBGR method shifts the values of the ColorMatrix into BGR order.
  • The ColorMatrix.multiply method multiplies two ColorMatrix data sets together.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Earcut has now been exposed and is available via Geom.Polygon.Earcut and is fully documented.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.
  • Pointer.downTime now stores the event timestamp of when the first button on the input device was pressed down, not just when button 1 was pressed down.
  • Pointer.upTime now stores the event timestamp of when the final depressed button on the input device was released, not just when button 1 was released.
  • The Pointer.getDuration method now uses the new Pointer downTime and upTime values, meaning it will accurately report the duration of when any button is being held down, not just the primary one. Fix #5112 (thanks @veleek)
  • The BaseShader default vertex shader now includes the outTexCoord vec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok)
  • When using the GameObjectCreator for Containers you can now specify the children property in the configuration object.
  • Textures.Parsers.JSONHash will now perform a hasOwnProperty check when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes from JSON.parse. Fix #4768 (thanks @RollinSafary)
  • The Camera3D Plugin has been rebuilt for Phaser 3.50 and the webpack config updated. This plugin is now considered deprecated and will not be updated beyond this release.
  • Tween.seek will no longer issue a console warning for 'Tween.seek duration too long', it's now up to you to check on the performance of tween seeking.
  • If inputWindowEvents is set in the Game Config, then the MouseManager will now listen for the events on window.top instead of just window, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in a try/catch block, as not all sites allow access to window.top (specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow)
  • MouseManager.isTop is a new boolean read-only property that flags if the mouse event listeners were attached to window.top (true), or just window (false). By default Phaser will attempt window.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back to window in those cases and set this property to false (thanks BunBunBun)
  • Types.GameObjects.Text.GetTextSizeObject is a new type def for the GetTextSize function results.
  • Utils.Array.StableSort has been recoded. It's now based on Two-Screens stable sort 0.1.8 and has been updated to fit into Phaser better and no longer create any window bound objects. The inplace function has been removed, just call StableSort(array) directly now. All classes that used StableSort.inplace have been updated to call it directly.
  • If a Scene is paused, or sent to sleep, it will automatically call Keyboard.resetKeys. This means that if you hold a key down, then sleep or pause a Scene, then release the key and resume or wake the Scene, it will no longer think it is still being held down (thanks @samme)
  • Actions.setOrigin will now call updateDisplayOrigin on the items array, otherwise the effects can't be seen when rendering.
  • You can now set the ArcadeWorld.fixedStep property via the ArcadeWorldConfig object (thanks @samme)
  • Utils.Array.NumerArray can now accept the start and end parameters in reverse order, i.e. 10, 1 will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.
  • DataManager.Events.DESTROY is a new event that the Data Manager will listen for from its parent and then call its own destroy method when received.
  • The Quaternion class constructor will now default the values to 0,0,0,1 if they're not provided, making it an identity quaternion, rather than the 0,0,0,0 it was before.
  • You can now set the ParticleEmitter.reserve value via the emitter configuration object (thanks @vforsh)
  • Setting the pixelArt config option will now set antialiasGL to false, as well as antialias. Fix #5309 (thanks @Vegita2)
  • The Shape class now includes the ComputedSize component properties and methods directly in the class, rather than applying as a mixin. setSize is now flagged as being private, because it shouldn't be used on Shape classes, which was leading to confusion as it appeared in the public-facing API. Fix #4811 (thanks @aolsx)
  • The Loader.maxParallelDownloads value is now set to 6 if running on Android, or 32 on any other OS. This avoids net::ERR_FAILED issues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary)
  • When running an Arcade Physics overlap test against a StaticBody, it will no longer set the blocked states of the dynamic body. If you are doing a collision test, they will still be set, but they're skipped for overlap-only tests. Fix #4435 (thanks @samme)
  • The Line Game Object will now default its width and height to 1, rather than zero. This allows you to give Line objects a physics body (although you will still need to re-adjust the center of the body manually). Fix #4596 (thanks @andrewaustin)
  • Internally, the Quaternion class now has 4 new private properties: _x, _y, _z and _w and 4 new getters and setters for the public versions. It also now passes most methods via set to allow for the onChange callback to be invoked. This does not change the public-facing API.
  • Group now extends EventEmitter, allowing you to emit custom events from within a Group.
  • Device.Audio.wav now uses audio/wav as the canPlayType check string, instead of audio/wav; codecs="1", which should allow iOS13 to play wav files again.
  • In the Loader.FileTypes.TextFile config you can now override the type and cache destination for the file.
  • Loader.MultiFile will now parse the given files array and only add valid entries into the file list, allowing multifiles to now have optional file entries.
  • The ParticleEmitter.tint value is now 0xffffff (previously, it was 0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh)
  • SceneManager.start will now reset the SceneSystems.sceneUpdate reference to NOOP. This gets set back to the Scene update method again during bootScene (if it has one) and stops errors with external plugins and multi-part files that may trigger update before create has been called. Fix #4629 (thanks @Osmose)
  • Phaser.Scene.renderer is a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.
  • The CanvasRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.
  • Since iOS 13, iPads now identify as MacOS devices. A new maxTouchPoint check is now part of the Device.OS tests, stopping iPads from being flagged as desktop devices. Fix #5389 (thanks @SBCGames)
  • The BitmapMask.prevFramebuffer property has been removed as it's no longer required, due to the fbo stack in the renderer.
  • The TextureManager.addGLTexture method has been updated so that the width and height parameters are now optional. If not provided, and if available, they will be read from the given WebGLTexture instead (thanks @hexus)
  • GameObjects.Components.Depth.depthList is a new property that all Game Objects that have the Depth Component now have. It contains a reference to the List responsible for managing the depth sorting of the Game Object. This is typically the Scene Display List, but can also be a Layer. It allows the Depth component to queue a depth sort directly on the list it belongs to now, rather than just the Scene.
  • The WebAudioSoundManager will no longer try to unlock itself if the Game hasn't already booted and been added to the DOM. It will now wait for the BOOT event and unlock based on that. Fix #5439 (thanks @samme)

Bug Fixes

  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)
  • The GridAlign action didn't work if only the height parameter was set. Fix #5019 (thanks @halilcakar)
  • The Color.HSVToRGB function has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX)
  • Previously, the easeParams array within a Tweens props object, or a multi-object tween, were ignored and it was only used if set on the root Tween object. It will now work correctly set at any depth. Fix #4292 (thanks @willblackmore)
  • When using Camera.setRenderToTexture its zoom and rotation values would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok)
  • GameObjects.Shape.Grid would render a white fill even if you passed undefined as the fill color in the constructor. It now doesn't render cells if no fill color is given.
  • The onMouse events in the Input Manager didn't reset the activePointer property to the mouse, meaning on dual-input systems such as Touch Screen devices, the active pointer would become locked to whichever input method was used first. Fix #4615 #5232 (thanks @mmolina01 @JstnPwll @Legomite)
  • The Scale Managers GetScreenOrientation function will now check for window.orientation first, because iOS mobile browsers have an incomplete implementation of the Screen API, forcing us to use the window value as a priority. This means the Scale Manager will now emit orientationchange events correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu)
  • Time.Clock.addEvent can now take an instance of a TimerEvent as its parameter. Fix #5294 (thanks @samme @EmilSV)
  • GameConfig.audio now defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)
  • The Loader.path was being added to the File URL even if the URL was absolute. This is now checked for and the path is not applied unless the URL is relative (thanks @firesoft)
  • Group.getMatching would always return an empty array. It now returns matching children (thanks @samme)
  • The ParticleManagerWebGLRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in follow offsets separately. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers. Fix #5319 #5195 #4739 #4691 (thanks @vforsh @condeagustin @IvanDem @Formic)
  • The ParticleManagerCanvasRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also uses setToContext internally. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers, or having the Camera zoomed, running under Canvas. Fix #4908 #4531 #4131 (thanks @smjnab @SirLink @jhooper04)
  • The Graphics WebGL Renderer will now default to pathOpen = true. This fixes issues under WebGL where, for example, adding an arc and calling strokePath, without first calling beginPath will no longer cause rendering artefacts when WebGL tries to close the path with a single tri.
  • Graphics.strokeRoundedRect now issues moveTo commands as part of the drawing sequence, preventing issues under WebGL where on older Android devices it would project additional vertices into the display. Fix #3955 (thanks @alexeymolchan)
  • Creating a Bitmap Mask from a texture atlas that was then used to mask another Game Object also using that same texture atlas would throw the error GL_INVALID_OPERATION : glDrawArrays: Source and destination textures of the draw are the same.. It now renders as expected. Fix #4675 (thanks @JacobCaron)
  • When using the same asset for a Game Object to be used as a mask, it would make other Game Objects using the same asset, that appeared above the mask in the display list, to not render. Fix #4767 (thanks @smjnab)
  • When taking a snapshot in WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in the WebGLSnapshot function. Fix #4956 (thanks @gammafp @telinc1)
  • Particles.EmitterOp.setMethods will now reset both onEmit and onUpdate to their default values. This allows you to reconfigure an emitter op with a new type of value and not have it stuck on the previous one. Fix #3663 (thanks @samme)
  • Particles.EmitterOp now cleanly separates between the different types of property configuration options. start | end will now ease between the two values, min | max will pick a random value between them and random: [] will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)
  • When setting both transparent: true and backgroundColor in the Game Config, it would ignore the transparency and use the color anyway. If transparent, the game is now fully transparent. Fix #5362 (thanks @Hoshinokoe)
  • The Ellipse Game Object now will update the width, height, and geometric position in the setSize method (thanks @PhaserEditor2D)
  • When measuring the last word in a line in a Text Game Object, it no longer adds extra white space to the end (thanks @rexrainbow)
  • Utils.Array.Remove would return an incorrect array of removed elements if one of the items to be removed was skipped in the array. Fix #5398 (thanks @year221)
  • Geom.Intersects.TriangleToLine wouldn't return true if the start or end of the Line fell inside the Triangle, only if the entire Line did. It now checks the start and end points correctly. (thanks @wiserim)
  • Using a Bitmap Mask and a Blend Mode in WebGL would reset the blend mode when the mask was rendered, causing the Game Object to have no blend mode. Fix #5409 (thanks @jcyuan)
  • BitmapMask would become corrupted when resizing the Phaser Game, either via the Scale Manager or directly, because the framebuffer and texture it used for rendering was still at the old dimensions. The BitmapMask now listens for the Renderer RESIZE event and re-creates itself accordingly. Fix #5399 (thanks @Patapits)

Misc Changes

Loader Cache Changes

When loading any of the file types listed below it will no longer store the data file in the cache. For example, when loading a Texture Atlas using a JSON File, it used to store the parsed image data in the Texture Manager and also store the JSON in the JSON Cache under the same key. This has changed in 3.50. The data files are no longer cached, as they are not required by the textures once parsing is completed, which happens during load. This helps free-up memory. How much depends on the size of your data files. And also allows you to easily remove textures based on just their key, without also having to clear out the corresponding data cache.

  • AtlasJSONFile no longer stores the JSON in the JSON Cache once the texture has been created.
  • AtlasXMLFile no longer stores the XML in the XML Cache once the texture has been created.
  • UnityAtlasFile no longer stores the Text in the Text Cache once the texture has been created.
  • BitmapFontFile no longer stores the XML in the XML Cache once the texture has been created.
  • You can now use TextureManager.remove to remove a texture and not have to worry about clearing the corresponding JSON or XML cache entry as well in order to reload a new texture using the same key. Fix #5323 (thanks @TedGriggs)

Lights 2D Updates

The Light Game Object has been rewritten so it now extends the Geom.Circle object, as they shared lots of the same properties and methods anyway. This has cut down on duplicate code massively.

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

Removal of 'resolution' property from across the API

For legacy reasons, Phaser 3 has never properly supported HighDPI devices. It will render happily to them of course, but wouldn't let you set a 'resolution' for the Canvas beyond 1. Earlier versions of 3.x had a resolution property in the Game Config, but it was never fully implemented (for example, it would break zooming cameras). When the Scale Manager was introduced in v3.16 we forced the resolution to be 1 to avoid it breaking anything else internally.

For a long time, the 'resolution' property has been present - taunting developers and confusing new comers. In this release we have finally gone through and removed all references to it. The Game Config option is now gone, it's removed from the Scale Manager, Base Camera and everywhere else where it matters. As much as we would have liked to implement the feature, we've spent too long without it, and things have been built around the assumption it isn't present. The API just wouldn't cope with having it shoe-horned in at this stage. As frustrating as this is, it's even more annoying to just leave the property there confusing people and wasting CPU cycles. Phaser 4 has been built with HighDPI screens in mind from the very start, but it's too late for v3. The following changes are a result of this removal:

  • The Phaser.Scale.Events#RESIZE event no longer sends the resolution as a parameter.
  • The BaseCamera.resolution property has been removed.
  • The internal private BaseCamera._cx, _cy, _cw and _ch properties has been removed, use x, y, width and height instead.
  • The BaseCamera.preRender method no longer receives or uses the resolution parameter.
  • The Camera.preRender method no longer receives or uses the resolution parameter.
  • The CameraManager.onResize method no longer receives or uses the resolution parameter.
  • The Core.Config.resolution property has been removed.
  • The TextStyle.resolution property is no longer read from the Game Config. You can still set it via the Text Style config to a value other than 1, but it will default to this now.
  • The CanvasRenderer no longer reads or uses the Game Config resolution property.
  • The PipelineManager.resize method along with WebGLPipeline.resize and anything else that extends them no longer receives or uses the resolution parameter.
  • The WebGLRenderer.resize and onResize methods no longer receives or uses the resolution parameter.
  • The ScaleManager.resolution property has been removed and all internal use of it.

Removal of 'interpolationPercentage' parameter from across the API

Since v3.0.0 the Game Object render functions have received a parameter called interpolationPercentage that was never used. The renderers do not calculate this value and no Game Objects apply it, so for the sake of clairty, reducing code and removing complexity from the API it has been removed from every single function that either sent or expected the parameter. This touches every single Game Object and changes the parameter order as a result, so please be aware of this if you have your own custom Game Objects, or plugins, that implement their own render methods. In terms of surface API changes, you shouldn't notice anything at all from this removal.

Namespace Updates

  • The Phaser.Curves.MoveTo function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.DOM.GetInnerHeight function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Bob class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsManager class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsPlugin class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Particles.EmitterOp class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.GetTextSize function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.MeasureText function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.TextStyle function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Input.CreatePixelPerfectHandler function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapCirc function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapRect function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Tilemap namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Components namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.MatterGameObject class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.PointerConstraint class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetPhysicsPlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetScenePlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Structs.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Tilemaps.Parsers.Tiled function has now been exposed on the Phaser namespace (thanks @samme)
  • Every single Tilemap.Component function has now been made public. This means you can call the Component functions directly, should you need to, outside of the Tilemap system.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360 @volkans80 @jaabberwocky @maikthomas @atursams @LearningCode2023 @DylanC @BenjaminDRichards @rexrainbow @Riderrr @spwilson2 @EmilSV @PhaserEditor2D @Gangryong @vinerz @trynx @usufruct99 @pirateksh @justin-calleja @monteiz

3.50 Beta Testing Help

A special mention to the following who submitted feedback on the 3.50 Beta releases:

@gammafp Acorn @BlunT76 @PhaserEditor2D @samme @rexrainbow @vforsh @kainage @ccaleb @spayton @FloodGames @buzzjeux @jcyuan @MadDogMayCry0 @Patapits @MMontalto @SBCGames @juanitogan @Racoonacoon @EmilSV @telinc1 @d7561985 @RollinSafary

Sorry if I forgot you!

- JavaScript
Published by photonstorm over 5 years ago

phaser - Phaser v3.50.0 Beta 12

Version 3.50.0 - Subaru - in development

WebGL Pipeline Updates

If you use a custom WebGL Pipeline in your game, you must update your code in order to use Phaser 3.50.

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

There is also the new GraphicsPipeline. Previously, the TextureTintPipeline was responsible for rendering all Sprites, Graphics and Shape objects. Now, it only renders Sprites. All Graphics and Shapes are handled by the new GraphicsPipeline which uses its own shaders. See further below for details about this change.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

Other pipeline changes are as follows:

  • None of the shaders or pipelines use the uViewMatrix and uModelMatrix uniforms any longer. These were always just plain identity matrices, so there is no point spending CPU and GPU time to set them as uniforms, or use them in the shaders. Should you need these uniforms, you can add them to your own custom pipelines.
  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.
  • The WebGLPipeline.shouldFlush method now accepts an optional parameter amount. If given, it will return true if when the amount is added to the vertex count it will exceed the vertex capacity. The Multi Pipeline has been updated to now use this method instead of performing the comparison multiple times itself.
  • The RopePipeline now extends MultiPipeline and just changes the topolgy, vastly reducing the filesize.
  • The WebGLPipeline.flushLocked property has been removed. A pipeline can never flush in the middle of a flush anyway, so it was just wasting CPU cycles being set.
  • You can now pass a pipeline instance to the GameObject.setPipeline method, as well as a string.

Post FX Pipelines

TODO - Explain them here + pipeline component updates.

Pipeline Uniform Changes

Piplines now have a new uniforms array that can be passed in with the config. All default pipelines now set these. The array contains the names, as strings, of all uniforms your pipeline shader uses. Once the pipeline shader has been successfully linked, it will use the array of names to look-up the WebGLUniformLocation of all uniforms specified. These are stored in the new WebGLPipeline.uniforms object. This takes place in the new WebGLPipeline.setUniformLocations method.

When a pipeline is bound, you can now use the new methods (listed below) to set uniform values directly on the pipeline. Previously, calling a method such as setFloat3 on a pipeline would pass that call over to WebGLRenderer. The renderer would first check to see if the pipeline program was current, and if not, make it so, before then looking up the uniform location and finally setting it. This is a lot of steps to take for pipelines that potentially need to change uniforms for every Game Object they render.

Under the new methods, and using the new pre-cached uniform locations, these extra steps are skipped. The uniform value is set directly, no shader binding takes place and no location look-up happens. This dramatically reduces the number of WebGL ops being issued per frame. To clearly differentiate these pipline methods, we have renamed them. The new method names are as follows:

  • WebGLPipeline.set1f will set a 1f uniform based on the given name.
  • WebGLPipeline.set2f will set a 2f uniform based on the given name.
  • WebGLPipeline.set3f will set a 3f uniform based on the given name.
  • WebGLPipeline.set4f will set a 4f uniform based on the given name.
  • WebGLPipeline.set1fv will set a 1fv uniform based on the given name.
  • WebGLPipeline.set2fv will set a 2fv uniform based on the given name.
  • WebGLPipeline.set3fv will set a 3fv uniform based on the given name.
  • WebGLPipeline.set4fv will set a 4fv uniform based on the given name.
  • WebGLPipeline.set1iv will set a 1iv uniform based on the given name.
  • WebGLPipeline.set2iv will set a 2iv uniform based on the given name.
  • WebGLPipeline.set3iv will set a 3iv uniform based on the given name.
  • WebGLPipeline.set4iv will set a 4iv uniform based on the given name.
  • WebGLPipeline.set1i will set a 1i uniform based on the given name.
  • WebGLPipeline.set2i will set a 2i uniform based on the given name.
  • WebGLPipeline.set3i will set a 3i uniform based on the given name.
  • WebGLPipeline.set4i will set a 4i uniform based on the given name.
  • WebGLPipeline.setMatrix2fv will set a matrix 2fv uniform based on the given name.
  • WebGLPipeline.setMatrix3fv will set a matrix 3fv uniform based on the given name.
  • WebGLPipeline.setMatrix4fv will set a matrix 4fv uniform based on the given name.

If your code uses any of the old method names, please update them using the list below:

  • WebGLPipeline.setFloat1 has been removed. Please use set1f instead.
  • WebGLPipeline.setFloat2 has been removed. Please use set2f instead.
  • WebGLPipeline.setFloat3 has been removed. Please use set3f instead.
  • WebGLPipeline.setFloat4 has been removed. Please use set4f instead.
  • WebGLPipeline.setFloat1v has been removed. Please use set1fv instead.
  • WebGLPipeline.setFloat2v has been removed. Please use set2fv instead.
  • WebGLPipeline.setFloat3v has been removed. Please use set3fv instead.
  • WebGLPipeline.setFloat4v has been removed. Please use set4fv instead.
  • WebGLPipeline.setInt1 has been removed. Please use set1i instead.
  • WebGLPipeline.setInt2 has been removed. Please use set2i instead.
  • WebGLPipeline.setInt3 has been removed. Please use set3i instead.
  • WebGLPipeline.setInt4 has been removed. Please use set4i instead.
  • WebGLPipeline.setMatrix1 has been removed. Please use setMatrix2fv instead.
  • WebGLPipeline.setMatrix2 has been removed. Please use setMatrix3fv instead.
  • WebGLPipeline.setMatrix3 has been removed. Please use setMatrix4fv instead.

Pipeline Manager

The WebGL.PipelineManager is a new class that is responsbile for managing all of the WebGL Pipelines in Phaser. An instance of the Pipeline Manager is created by the WebGL Renderer and is available under the pipelines property. This means that the WebGL Renderer no longer handles pipelines directly, causing the following API changes:

  • WebGLRenderer.pipelines is no longer a plain object containing pipeline instances. It's now an instance of the PipelineManager class. This instance is created during the init and boot phase of the renderer.
  • The WebGLRenderer.currentPipeline property no longer exists, instead use PipelineManager.current.
  • The WebGLRenderer.previousPipeline property no longer exists, instead use PipelineManager.previous.
  • The WebGLRenderer.hasPipeline method no longer exists, instead use PipelineManager.has.
  • The WebGLRenderer.getPipeline method no longer exists, instead use PipelineManager.get.
  • The WebGLRenderer.removePipeline method no longer exists, instead use PipelineManager.remove.
  • The WebGLRenderer.addPipeline method no longer exists, instead use PipelineManager.add.
  • The WebGLRenderer.setPipeline method no longer exists, instead use PipelineManager.set.
  • The WebGLRenderer.rebindPipeline method no longer exists, instead use PipelineManager.rebind.
  • The WebGLRenderer.clearPipeline method no longer exists, instead use PipelineManager.clear.

The Pipeline Manager also offers the following new features:

  • The PipelineManager.resize method automatically handles resize events across all pipelines.
  • The PipelineManager.preRender method calls the pre-render method of all pipelines.
  • The PipelineManager.render method calls the render method of all pipelines.
  • The PipelineManager.postRender method calls the post-render method of all pipelines.
  • The PipelineManager.setMulti method automatically binds the Multi Texture Pipeline, Phaser's default.
  • The PipelineManager.clear method will clear the pipeline, store it in previous and free the renderer.
  • The PipelineManager.rebind method will reset the rendering context and restore the previous pipeline, if set.

New constants have been created to help you reference a pipeline without needing to use strings:

  • Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE for the Bitmap Mask Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE for the Light 2D Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE for the Single Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE for the Multi Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE for the Rope Pipeline.

All Game Objects have been updated to use the new constants and Pipeline Manager.

Single Pipeline

There is also a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGL Multi-Texture Rendering

The Multi Pipeline (previously called the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw-call bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLPipeline.forceZero is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.
  • The WebGL.Utils.getComponentCount function has been removed as this is no longer required internally.

WebGLRenderer New Features, Updates and API Changes

  • WebGLRenderer.instancedArraysExtension is a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.
  • WebGLRenderer.vaoExtension is a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.
  • WebGLRenderer.resetProgram is a new method that will rebind the current program, without flushing or changing any properties.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • WebGLRenderer.finalType is a new boolean property that signifies if the current Game Object being rendered is the final one in the list.
  • The WebGLRenderer.updateCanvasTexture method will now set gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL to true, which should stop issues where you update a Text Game Object, having added a Render Texture or Spine Game Object to the Scene after it, which switches the PMA setting. Fix #5064 #5155 (thanks @hugoruscitti @immangrove-supertree)
  • WebGLRenderer.previousPipeline is a new property that is set during a call to clearPipeline and used during calls to rebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.
  • The WebGLRenderer.rebindPipeline method has been changed slightly. Previously, you had to specify the pipelineInstance, but this is now optional. If you don't, it will use the new previousPipeline property instead. If not set, or none given, it will now return without throwing gl errors as well.
  • WebGLRenderer.defaultScissor is a new property that holds the default scissor dimensions for the renderer. This is modified during resize and avoids continuous array generation in the preRender loop.
  • The WebGLRenderer.nativeTextures array has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in the TextureSource objects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy.
  • The WebGLRenderer.deleteTexture method has a new optional boolean parameter reset which allows you to control if the WebGLRenderer.resetTextures method is called, or not, after the texture is deleted.
  • The WebGLRenderer.getMaxTextures method has been removed. This is no longer needed as you can use the WebGLRenderer.maxTextures property instead.
  • The WebGLRenderer.setProgram method now returns a boolean. true if the program was set, otherwise false.
  • The WebGLRenderer.setVertexBuffer method now returns a boolean. true if the buffer was set, otherwise false.
  • WebGLRenderer.setFloat1 has been removed. Use WebGLPipeline.set1f or WebGLShader.set1f instead.
  • WebGLRenderer.setFloat2 has been removed. Use WebGLPipeline.set2f or WebGLShader.set2f instead.
  • WebGLRenderer.setFloat3 has been removed. Use WebGLPipeline.set3f or WebGLShader.set3f instead.
  • WebGLRenderer.setFloat4 has been removed. Use WebGLPipeline.set4f or WebGLShader.set4f instead.
  • WebGLRenderer.setFloat1v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set1fv instead.
  • WebGLRenderer.setFloat2v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set2fv instead.
  • WebGLRenderer.setFloat3v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set3fv instead.
  • WebGLRenderer.setFloat4v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set4fv instead.
  • WebGLRenderer.setInt1 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set1i instead.
  • WebGLRenderer.setInt2 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set2i instead.
  • WebGLRenderer.setInt3 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set3i instead.
  • WebGLRenderer.setInt4 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set4i instead.
  • WebGLRenderer.setMatrix2 has been removed. Use WebGLPipeline.setMatrix2fv or WebGLShader.setMatrix2fv instead.
  • WebGLRenderer.setMatrix3 has been removed. Use WebGLPipeline.setMatrix3fv or WebGLShader.setMatrix3fv instead.
  • WebGLRenderer.setMatrix4 has been removed. Use WebGLPipeline.setMatrix4fv or WebGLShader.setMatrix4fv instead.
  • The WebGLRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.
  • WebGLRenderer.fboStack is a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.
  • WebGLRenderer.pushFramebuffer is a new method that is used to push a framebuffer onto the fbo stack before setting it as the current framebuffer. This should now be called in place of setFramebuffer. Remember to call popFramebuffer after using it.
  • WebGLRenderer.popFramebuffer is a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.
  • WebGLRenderer.setFramebuffer has a new optional boolean parameter resetTextures which will reset the WebGL Textures, if set to true (which is the default).
  • WebGLRenderer.isBooted is a new boolean property that lets you know if the rendere has fully finished booting.
  • The WebGLRenderer now extends the Event Emitter, allowing you to listen to renderer specific events.
  • Phaser.Renderer.WebGL.Events is a new WebGL Renderer namespace for events.
  • WebGL.Events.PRE_RENDER is a new event dispatched by the WebGL Renderer. This happens right at the start of the render process.
  • WebGL.Events.RENDER is a new event dispatched by the WebGL Renderer. This happens once for every camera, in every Scene at the start of its render process.
  • WebGL.Events.POST_RENDER is a new event dispatched by the WebGL Renderer. This happens right at the end of the render process.
  • WebGL.Events.RESIZE is a new event dispatched by the WebGL Renderer whenever it is resized.

Camera - New Features, Updates and API Changes

The Camera API has changed in line with the new pipeline updates. To this end, the following changes have taken place:

The Camera class now inherits the Pipeline Component. This gives it new features, in line with the other pipelines changes in 3.50, such as Camera.setPipeline, Camera.setPostPipeline, Camera.setPipelineData and so on. This is a much more powerful and flexible way of setting camera effects, rather than it managing its own framebuffer and texture directly.

To that end, the following properties and methods have been removed to tidy things up:

  • The Camera.renderToTexture property has been removed. Effects are now handled via pipelines.
  • The Camera.renderToGame property has been removed. Effects are now handled via pipelines.
  • The Camera.canvas property has been removed. Textures are handled by pipelines.
  • The Camera.context property has been removed. Textures are handled by pipelines.
  • The Camera.glTexture property has been removed. GL Textures are handled by pipelines.
  • The Camera.framebuffer property has been removed. GL Framebuffers are handled by pipelines.
  • The Camera.setRenderToTexture method has been removed. Effects are now handled via pipelines.
  • The Camera.clearRenderToTexture method has been removed. Effects are now handled via pipelines.

These changes mean that you can no longer render a Camera to a canvas in Canvas games.

Other changes and fixes:

  • Camera.zoomX is a new property that allows you to specifically set the horizontal zoom factor of a Camera.
  • Camera.zoomY is a new property that allows you to specifically set the vertical zoom factor of a Camera.
  • The Camera.setZoom method now allows you to pass two parameters: x and y, to control the zoomX and zoomY values accordingly.
  • The Camera.zoom property now returns an average of the zoomX and zoomY properties.
  • Cameras.Scene2D.Events.FOLLOW_UPDATE is a new Event that is dispatched by a Camera when it is following a Game Object. It is dispatched every frame, right after the final Camera position and internal matrices have been updated. Use it if you need to react to a camera, using its most current position and the camera is following something. Fix #5253 (thanks @rexrainbow)
  • If the Camera has roundPixels set it will now round the internal scroll factors and worldView during the preRender step. Fix #4464 (thanks @Antriel)

Graphics Pipeline and Graphics Game Object Changes

The Graphics Pipeline is a new pipeline added in 3.50 that is responsible for rendering Graphics Game Objects and all of the Shape Game Objects, such as Arc, Rectangle, Star, etc. Due to the new pipeline some changes have been made:

  • The Graphics Pipeline now uses much simpler vertex and fragment shaders, with just two attributes (inPosition and inColor), making the vertex size and memory-use 57% smaller.
  • The private _tempMatrix1, 2, 3 and 4 properties have all been removed from the pipeline.
  • A new public calcMatrix property has been added, which Shape Game Objects use to maintain transform state during rendering.
  • The Graphics Pipeline no longer makes use of tintEffect or any textures.
  • Because Graphics and Shapes now render with their own pipeline, you are able to exclude the pipeline and those Game Objects entirely from custom builds, further reducing the final bundle size.

As a result of these changes the following features are no longer available:

  • Graphics.setTexture has been removed. You can no longer use a texture as a 'fill' for a Graphic. It never worked with any shape other than a Rectangle, anyway, due to UV mapping issues, so is much better handled via the new Mesh Game Object.
  • Graphics._tempMatrix1, 2 and 3 have been removed. They're not required internally any longer.
  • Graphics.renderWebGL now uses the standard GetCalcMatrix function, cutting down on duplicate code significantly.

Render Texture Game Object - New Features, API Changes and Bug Fixes

The Render Texture Game Object has been rewritten to use the new RenderTarget class internally, rather than managing its own framebuffer and gl textures directly. The core draw methods are now a lot simpler and no longer require manipulating render pipelines.

As a result of these changes the following updates have happened:

  • RenderTexture.renderTarget is a new property that contains a RenderTarget instance, which is used for all drawing.
  • The RenderTexture.framebuffer property has been removed. You can now access this via RenderTexture.renderTarget.framebuffer.
  • The RenderTexture.glTexture property has been removed. You can now access this via RenderTexture.renderTarget.texture.
  • The RenderTexture.gl property has been removed.

Render Textures have the following new features:

  • RenderTexture.beginDraw is a new method that allows you to create a batched draw to the Render Texture. Use this method to begin the batch.
  • RenderTexture.batchDraw is a new method that allows you to batch the drawing of an object to the Render Texture. You should never call this method unless you have previously started a batch with beginDraw. You can call this method as many times as you like, to draw as many objects as you like, without causing a framebuffer bind.
  • RenderTexture.batchDrawFrame is a new method that allows you to batch the drawing of a texture frame to the Render Texture. You should never call this method unless you have previously started a batch with beginDraw. You can call this method as many times as you like, to draw as many frames as you like, without causing a framebuffer bind.
  • RenderTexture.endDraw is a new method that ends a previously created batched draw on the Render Texture. Use it to write all of your batch changes to the Render Texture.
  • You can now draw a Group to a RenderTexture. Previously, it failed to pass the camera across, resulting in none of the Group children being drawn. Fix #5330 (thanks @somnolik)

Render Textures have the following bug fixes:

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • RenderTexture.erase has never worked when using the Canvas Renderer and a texture frame, only with Game Objects. It now works with both. Fix #5422 (thanks @vforsh)

Light Pipeline Changes

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh Game Objects now support rendering with normal maps.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Lights

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

WebGL ModelViewProjection Removed

The ModelViewProjection object contained a lot of functions that Phaser never used internally. Instead, the functions available in them were already available in the Math.Matrix4 class. So the pipelines have been updated to use a Matrix4 instead and all of the MVP functions have been removed. The full list of removed functions is below:

  • projIdentity has been removed.
  • projPersp has been removed.
  • modelRotateX has been removed.
  • modelRotateY has been removed.
  • modelRotateZ has been removed.
  • viewLoad has been removed.
  • viewRotateX has been removed.
  • viewRotateY has been removed.
  • viewRotateZ has been removed.
  • viewScale has been removed.
  • viewTranslate has been removed.
  • modelIdentity has been removed.
  • modelScale has been removed.
  • modelTranslate has been removed.
  • viewIdentity has been removed.
  • viewLoad2D has been removed.
  • projOrtho has been removed.

BitmapText - New Features, Updates and API Changes

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has to work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.
  • You can now use setMaxWidth on DynamicBitmapText, which wasn't previously possible. Fix #4997 (thanks @AndreaBoeAbrahamsen)

Update List Changes

The way in which Game Objects add themselves to the Scene Update List has changed. Instead of being added by the Factory methods, they will now add and remove themselves based on the new ADDED_TO_SCENE and REMOVED_FROM_SCENE events. This means, you can now add Sprites directly to a Container, or Group, and they'll animate properly without first having to be part of the Update List. The full set of changes and new features relating to this follow:

  • GameObjects.Events.ADDED_TO_SCENE is a new event, emitted by a Game Object, when it is added to a Scene, or a Container that is part of the Scene.
  • GameObjects.Events.REMOVED_FROM_SCENE is a new event, emitted by a Game Object, when it is removed from a Scene, or a Container that is part of the Scene.
  • Scenes.Events.ADDED_TO_SCENE is a new event, emitted by a Scene, when a new Game Object is added to the display list in the Scene, or a Container that is on the display list.
  • Scenes.Events.REMOVED_FROM_SCENE is a new event, emitted by a Scene, when it a Game Object is removed from the display list in the Scene, or a Container that is on the display list.
  • GameObject.addedToScene is a new method that custom Game Objects can use to perform additional set-up when a Game Object is added to a Scene. For example, Sprite uses this to add itself to the Update List.
  • GameObject.removedFromScene is a new method that custom Game Objects can use to perform additional tear-down when a Game Object is removed from a Scene. For example, Sprite uses this to remove themselves from the Update List.
  • Game Objects no longer automatically remove themselves from the Update List during preDestroy. This should be handled directly in the removedFromScene method now.
  • The Container will now test to see if any Game Object added to it is already on the display list, or not, and emit its ADDED and REMOVED events accordingly. Fix #5267 #3876 (thanks @halgorithm @mbpictures)
  • DisplayList.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • DisplayList.addChildCallback is a new method that overrides the List callback and fires the new ADDED events.
  • DisplayList.removeChildCallback is a new method that overrides the List callback and fires the new REMOVED events.
  • GameObjectCreator.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • GameObjectFactory.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • ProcessQueue.checkQueue is a new boolean property that will make sure only unique objects are added to the Process Queue.
  • The Update List now uses the new checkQueue property to ensure no duplicate objects are on the active list.
  • DOMElementFactory, ExternFactory, ParticleManagerFactor, RopeFactory and SpriteFactory all no longer add the objects to the Update List, this is now handled by the ADDED events instead.
  • Sprite, Rope, ParticleEmitterManager, Extern and DOMElement now all override the addedToScene and removedFromScene callbacks to handle further set-up tasks.

Spine Plugin Updates

  • The Spine Runtimes have been updated to 3.8.99, which are the most recent non-beta versions. Please note, you will need to re-export your animations if you're working in a version of Spine lower than 3.8.20.
  • SpineContainer is a new Game Object available via this.add.spineContainer to which you can add Spine Game Objects only. It uses a special rendering function to retain batching, even across multiple container or Spine Game Object instances, resulting in dramatically improved performance compared to using regular Containers. You can still use regular Containers if you need, but they do not benefit from the new batching.
  • A Spine Game Object with setVisible(false) will no longer still cause internal gl commands and is now properly skipped, retaining any current batch in the process. Fix #5174 (thanks @Kitsee)
  • The Spine Game Object WebGL Renderer will no longer clear the type if invisible and will only end the batch if the next type doesn't match.
  • The Spine Game Object WebGL Renderer will no longer rebind the pipeline if it was the final object on the display list, saving lots of gl commands.
  • The Webpack build scripts have all been updated for Webpack 4.44.x. Fix #5243 (thanks @RollinSafary)
  • There is a new npm script npm run plugin.spine.runtimes which will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo into plugins/spine/ in order for this to work and then run npm i.
  • Spine Game Objects can now be rendered to Render Textures. Fix #5184 (thanks @Kitsee)
  • Using > 128 Spine objects in a Container would cause a WebGL: INVALID_OPERATION: vertexAttribPointer: no ARRAY_BUFFER is bound and offset is non-zero error if you added any subsequent Spine objects to the Scene. There is now no limit. Fix #5246 (thanks @d7561985)
  • The Spine Plugin will now work in HEADLESS mode without crashing. Fix #4988 (thanks @raimon-segura)
  • Spine Game Objects now use -1 as their default blend mode, which means 'skip setting it', as blend modes should be handled by the Spine skeletons directly.
  • The Spine TypeScript defs have been updated for the latest version of the plugin and to add SpineContainers.
  • The SpineGameObject.setAnimation method will now use the trackIndex parameter if ignoreIfPlaying is set and run the check against this track index. Fix #4842 (thanks @vinerz)
  • The SpineFile will no longer throw a warning if adding a texture into the Texture Manager that already exists. This allows you to have multiple Spine JSON use the same texture file, however, it also means you now get no warning if you accidentally load a texture that exists, so be careful with your keys! Fix #4947 (thanks @Nomy1)
  • The Spine Plugin destroy method will now no longer remove the Game Objects from the Game Object Factory, or dispose of the Scene Renderer. This means when a Scene is destroyed, it will keep the Game Objects in the factory for other Scenes to use. Fix #5279 (thanks @Racoonacoon)
  • SpinePlugin.gameDestroy is a new method that is called if the Game instance emits a destroy event. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.
  • SpineFile will now check to see if another identical atlas in the load queue is already loading the texture it needs and will no longer get locked waiting for a file that will never complete. This allows multiple skeleton JSONs to use the same atlas data. Fix #5331 (thanks @Racoonacoon)
  • SpineFile now uses a ! character to split the keys, instead of an underscore, preventing the plugin from incorrectly working out the keys for filenames with underscores in them. Fix #5336 (thanks @Racoonacoon)
  • SpineGameObject.willRender is no longer hard-coded to return true. It instead now takes a Camera parameter and performs all of the checks needed before returning. Previously, this happened during the render functions.
  • The Spine Plugin now uses a single instance of the Scene Renderer when running under WebGL. All instances of the plugin (installed per Scene) share the same base Scene Renderer, avoiding duplicate allocations and resizing events under multi-Scene games. Fix #5286 (thanks @spayton BunBunBun)

Animation API - New Features and Updates

If you use Animations in your game, please read the following important API changes in 3.50:

The Animation API has had a significant overhaul to improve playback handling. Instead of just playing an animation based on its global key, you can now supply a new PlayAnimationConfig object instead, which allows you to override any of the default animation settings, such as duration, delay and yoyo (see below for the full list). This means you no longer have to create lots of duplicate animations just to change properties such as duration, and can now set them dynamically at run-time as well.

  • The Animation class no longer extends EventEmitter, as it no longer emits any events directly. This means you cannot now listen for events directly from an Animation instance. All of the events are now dispatched by the Game Objects instead.
  • All of the SPRITE_ANIMATION_KEY events have been removed. Instead, please use the new events which all carry the frameKey parameter, which can be used to handle frame specific events. The only exception to this is ANIMATION_COMPLETE_KEY, which is a key specific version of the completion event.
  • ANIMATION_UPDATE_EVENT is a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.
  • ANIMATION_STOP_EVENT is a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of the stop methods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)
  • The Game Object Component.Animation component has been renamed to AnimationState and has moved namespace. It's now in Phaser.Animations instead of GameObjects.Components to help differentiate it from the Animation class when browsing the documentation.
  • The play, playReverse, playAfterDelay, playAfterRepeat and chain Sprite and Animation Component methods can now all take a Phaser.Types.Animations.PlayAnimationConfig configuration object, as well as a string, as the key parameter. This allows you to override any default animation setting with those defined in the config, giving you far greater control over animations on a Game Object level, without needing to globally duplicate them.
  • AnimationState.create is a new method that allows you to create animations directly on a Sprite. These are not global and never enter the Animation Manager, instead risiding within the Sprite itself. This allows you to use the same keys across both local and global animations and set-up Sprite specific local animations.
  • AnimationState.generateFrameNumbers is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • AnimationState.generateFrameNames is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • All playback methods: play, playReverse, playAfterDelay and playAfterRepeat will now check to see if the given animation key exists locally on the Sprite first. If it does, it's used, otherwise it then checks the global Animation Manager for the key instead.
  • AnimationState.skipMissedFrames is now used when playing an animation, allowing you to create animations that run at frame rates far exceeding the refresh rate, or that will update to the correct frame should the game lag. Feature #4232 (thanks @colorcube)
  • AnimationManager.addMix is a new method that allows you to create mixes 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.
  • AnimationManager.getMix is a new method that will return the mix duration between the two given animations.
  • AnimationManager.removeMix is a new method that will remove the mixture between either two animations, or all mixtures for the given animation.
  • AnimationState.remove is a new method that will remove a locally stored Animation instance from a Sprite.
  • AnimationState.get is a new method that will return a locally stored Animation instance from the Sprite.
  • AnimationState.exists is a new method that will check if a locally stored Animation exists on the Sprite.
  • The internal AnimationState.remove method has been renamed to globalRemove.
  • AnimationState.textureManager is a new property that references the global Texture Manager.
  • AnimationState.anims is a new property that contains locally created Animations in a Custom Map.
  • AnimationState.play and Sprite.play no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • AnimationState.playReverse and Sprite.playReverse no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • The AnimationState.delayedPlay method has been renamed to playAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration.
  • The AnimationState.stopOnRepeat method has been renamed to stopAfterRepeat
  • The AnimationState.getCurrentKey method has been renamed to getName.
  • AnimationState.getFrameName is a new method that will return the key of the current Animation Frame, if an animation has been loaded.
  • AnimationState.playAfterDelay and Sprite.playAfterDelay are new methods that will play the given animation after the delay in ms expires.
  • AnimationState.playAfterRepeat and Sprite.playAfterRepeat are new methods that will play the given animation after the current animation finishes repeating. You can also specify the number of repeats allowed left to run.
  • The AnimationState.chain method is now available on the Sprite class.
  • The AnimationState.stopAfterDelay method is now available on the Sprite class.
  • The AnimationState.stopAfterRepeat method is now available on the Sprite class.
  • The AnimationState.stopOnFrame method is now available on the Sprite class.
  • AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser. Please see the comprehensive documentation for this method for full details on how to do this.
  • AnimationState now handles all of the loading of the animation. It no longer has to make calls out to the Animation Manager or Animation instance itself and will load the animation data directly, replacing as required from the optional PlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.
  • The PlayAnimationConfig.frameRate property lets you optionally override the animation frame rate.
  • The PlayAnimationConfig.duration property lets you optionally override the animation duration.
  • The PlayAnimationConfig.delay property lets you optionally override the animation delay.
  • The PlayAnimationConfig.repeat property lets you optionally override the animation repeat counter.
  • The PlayAnimationConfig.repeatDelay property lets you optionally override the animation repeat delay value.
  • The PlayAnimationConfig.yoyo property lets you optionally override the animation yoyo boolean.
  • The PlayAnimationConfig.showOnStart property lets you optionally override the animation show on start value.
  • The PlayAnimationConfig.hideOnComplete property lets you optionally override the animation hide on complete value.
  • The PlayAnimationConfig.startFrame property lets you optionally set the animation frame to start on.
  • The PlayAnimationConfig.timeScale property lets you optionally set the animation time scale factor.
  • AnimationState.delayCounter is a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animation START events fire. Fix #4426 (thanks @bdaenen)
  • AnimationState.hasStarted is a new boolean property that allows you to tell if the current animation has started playing, or is still waiting for a delay to expire.
  • AnimationState.showOnStart is a new boolean property that controls if the Game Object should have setVisible(true) called on it when the animation starts.
  • AnimationState.hideOnComplete is a new boolean property that controls if the Game Object should have setVisible(false) called on it when the animation completes.
  • The AnimationState.chain method docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does!
  • The AnimationState.setDelay method has been removed. It never actually worked and you can now perform the same thing by calling either playAfterDelay or setting the delay property in the play config.
  • The AnimationState.getDelay method has been removed. You can now read the delay property directly.
  • The AnimationState.setRepeat method has been removed. You can achieve the same thing by setting the repeat property in the play config, or adjusting the public repeatCounter property if the animation has started.
  • AnimationState.handleStart is a new internal private method that handles the animation start process.
  • AnimationState.handleRepeat is a new internal private method that handles the animation repeat process.
  • AnimationState.handleStop is a new internal private method that handles the animation stop process.
  • AnimationState.handleComplete is a new internal private method that handles the animation complete process.
  • AnimationState.emitEvents is a new internal private method that emits animation events, cutting down on duplicate code.
  • The AnimationState.restart method has a new optional boolean parameter resetRepeats which controls if you want to reset the repeat counter during the restart, or not.
  • Animation.getTotalFrames is a new method that will return the total number of frames in the animation. You can access it via this.anims.currentAnim.getTotalFrames from a Sprite.
  • Animation.calculateDuration is a new method that calculates the duration, frameRate and msPerFrame for a given animation target.
  • The BuildGameObjectAnimation function now uses the PlayAnimationConfig object to set the values.
  • Sprite.playReverse is a new method that allows you to play the given animation in reverse on the Sprite.
  • Sprite.playAfterDelay is a new method that allows you to play the given animation on the Sprite after a delay.
  • Sprite.stop is a new method that allows you to stop the current animation on the Sprite.
  • AnimationManager.load has been removed as it's no longer required.
  • AnimationManager.staggerPlay has been fixed so you can now pass in negative stagger values.
  • AnimationManager.staggerPlay has a new optional boolean parameter staggerFirst, which allows you to either include or exclude the first child in the stagger calculations.
  • The Animation.completeAnimation method has been removed as it's no longer required.
  • The Animation.load method has been removed as it's no longer required.
  • The Animation.setFrame method has been removed as it's no longer required.
  • The Animation.getFirstTick method has no longer needs the includeDelay parameter, as it's handled by AnimationState now.
  • The Animation.getFrames method has a new optional boolean parameter sortFrames which will run a numeric sort on the frame names after constructing them, if a string-based frame is given.
  • Types.Animations.Animation has a new boolean property sortFrames, which lets Phaser numerically sort the generated frames.
  • AnimationState.timeScale is a new public property that replaces the old private _timeScale property.
  • AnimationState.delay is a new public property that replaces the old private _delay property.
  • AnimationState.repeat is a new public property that replaces the old private _repeat property.
  • AnimationState.repeatDelay is a new public property that replaces the old private _repeatDelay property.
  • AnimationState.yoyo is a new public property that replaces the old private _yoyo property.
  • AnimationState.inReverse is a new public property that replaces the old private _reverse property.
  • AnimationState.startAnimation is a new public method that replaces the old private _startAnimation method.
  • The AnimationState.getProgress method has been fixed so it will return correctly if the animation is playing in reverse.
  • The AnimationState.globalRemove method will now always be called when an animation is removed from the global Animation Manager, not just once.
  • The AnimationState.getRepeat method has now been removed. You can get the value from the repeat property.
  • The AnimationState.setRepeatDelay method has now been removed. You can set the value using the repeatDelay config property, or changing it at run-time.
  • AnimationState.complete is a new method that handles the completion in animation playback.
  • The AnimationState.setTimeScale method has now been removed. You can set the value using the timeScale config property, or changing it at run-time.
  • The AnimationState.getTimeScale method has now been removed. You can read the value using the timeScale property.
  • The AnimationState.getTotalFrames method has been fixed and won't error if called when no animation is loaded.
  • The AnimationState.setYoyo method has now been removed. You can set the value using the yoyo config property, or changing it at run-time.
  • The AnimationState.getYoyo method has now been removed. You can read the value using the yoyo property.
  • The AnimationState.stopAfterRepeat method now has an optional parameter repeatCount, so you can tell the animation to stop after a specified number of repeats, not just 1.
  • When playing an animation in reverse, if it reached the first frame and had to repeat, it would then jump to the frame before the final frame and carry on, skipping out the final frame.
  • The AnimationState.updateFrame method has now been removed. Everything is handled by setCurrentFrame instead, which removes one extra step out of the update process.
  • GenerateFrameNames will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers would include the __BASE frame by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.
  • GenerateFrameNumbers can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.
  • GenerateFrameNames can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.

Tilemap - New Features, Updates and API Changes

There are three large changes to Tilemaps in 3.50. If you use tilemaps, you must read this section:

1) The first change is that there are no longer DynamicTilemapLayer and StaticTilemapLayer classes. They have both been removed and replaced with the new TilemapLayer class. This new class consolidates features from both and provides a lot cleaner API experience, as well as speeding up internal logic.

In your game where you use map.createDynamicLayer or map.createStaticLayer replace it with map.createLayer instead.

2) The second change is that the Tilemap system now supports isometric, hexagonal and staggered isometric map types, along with the previous orthogonal format, thanks to a PR from @svipal. You can now export maps using any of these orientations from the Tiled Map Editor and load them into Phaser using the existing tilemap loading API. No further changes need to take place in the way your maps are loaded.

3) The Tilemap.createFromObjects method has been overhauled to make it much more useful. The method signature has changed and it now takes a new CreateFromObjectLayerConfig configuration object, or an array of them, which allows much more fine-grained control over which objects in the Tiled Object Layers are converted and what they are converted to. Previously it could only convert to Sprites, but you can now pass in a custom class, filter based on id, gid or name, even provide a Container to add the created Game Objects to. Please see the new documentation for this method and the config object for more details. Fix #3817 #4613 (thanks @georgzoeller @Secretmapper)

  • The Tilemap.createDynamicLayer method has been renamed to createLayer.
  • The Tilemap.createStaticLayer method has been removed. Use createLayer instead.
  • The Tilemap.createBlankDynamicLayer method has been renamed to createBlankLayer.
  • The Tilemap.convertLayerToStatic method has been removed as it is no longer required.
  • The TilemapLayerWebGLRenderer function will no longer iterate through the layer tilesets, drawing tiles from only that set. Instead all it does now is iterate directly through only the tiles. This allows it to take advantage of the new Multi Texturing pipeline and also draw multi-tileset isometric layers correctly.
  • Phaser.Types.Tilemaps.TilemapOrientationType is a new type def that holds the 4 types of map orientation now supported.
  • The Tile.updatePixelXY method now updates the tile XY position based on map type.
  • ParseTilesets will now correctly handle non-consecutive tile IDs. It also now correctly sets the maxId property, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)
  • Tilemap.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • LayerData.orientation is a new property that holds the tilemap layers orientation constant.
  • LayerData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • MapData.orientation is a new property that holds the tilemap layers orientation constant.
  • MapData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • Tilemaps.Components.HexagonalWorldToTileY is a new function that converts a world Y coordinate to hexagonal tile Y coordinate.
  • Tilemaps.Components.StaggeredWorldToTileY is a new function that converts a world Y coordinate to staggered tile Y coordinate.
  • Tilemaps.Components.HexagonalWorldToTileXY is a new function that converts world coordinates to hexagonal tile coordinates.
  • Tilemaps.Components.IsometricWorldToTileXY is a new function that converts world coordinates to isometric tile coordinates.
  • Tilemaps.Components.StaggeredWorldToTileXY is a new function that converts world coordinates to staggered tile coordinates.
  • Tilemaps.Components.HexagonalTileToWorldY is a new function that converts a hexagonal Y coordinate to a world coordinate.
  • Tilemaps.Components.StaggeredTileToWorldY is a new function that converts a staggered Y coordinate to a world coordinate.
  • Tilemaps.Components.HexagonalTileToWorldXY is a new function that converts hexagonal tile coordinates to world coordinates.
  • Tilemaps.Components.IsometricTileToWorldXY is a new function that converts isometric tile coordinates to world coordinates.
  • Tilemaps.Components.StaggeredTileToWorldXY is a new function that converts staggered tile coordinates to world coordinates.
  • Tilemaps.Components.GetTileToWorldXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldXXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetCullTilesFunction is a new function that returns the correct culling function to use.
  • Tilemaps.Components.HexagonalCullTiles is a new function that culls tiles in a hexagonal map.
  • Tilemaps.Components.StaggeredCullTiles is a new function that culls tiles in a staggered map.
  • Tilemaps.Components.IsometricCullTiles is a new function that culls tiles in a isometric map.
  • Tilemaps.Components.CullBounds is a new function that calculates the cull bounds for an orthogonal map.
  • Tilemaps.Components.HexagonalCullBounds is a new function that calculates the cull bounds for a hexagonal map.
  • Tilemaps.Components.StaggeredCullBounds is a new function that calculates the cull bounds for a staggered map.
  • Tilemaps.Components.RunCull is a new function that runs the culling process from the combined bounds and tilemap.
  • Tilemap._convert is a new internal private hash of tilemap conversion functions used by the public API.
  • The Tilemap._isStaticCall method has been removed and no Tilemap methods now check this, leading to faster execution.
  • The Arcade Physics Sprites vs. Tilemap Layers flow has changed. Previously, it would iterate through a whole bunch of linked functions, taking lots of jumps in the process. It now just calls the GetTilesWithinWorldXY component directly, saving lots of overhead.
  • The method Tilemap.weightedRandomize has changed so that the parameter weightedIndexes is now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional.
  • The method TilemapLayer.weightedRandomize has changed so that the parameter weightedIndexes is now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional.

Mesh Game Object - New Features, Updates and API Changes

The Mesh Game Object has been rewritten from scratch in v3.50 with a lot of changes to make it much more useful. It is accompanied by the new Geom.Mesh set of functions.

  • Geom.Mesh is a new namespace that contains the Mesh related geometry functions. These are stand-alone functions that you may, or may not require, depending on your game.
  • Geom.Mesh.Vertex is a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.
  • Geom.Mesh.Face is a new class that consists of references to the three Vertex instances that construct a single Face in a Mesh and provides methods for manipulating them.
  • Geom.Mesh.GenerateVerts is a new function that will return an array of Vertex and Face objects generated from the given data. You can provide index, or non-index vertex lists, along with UV data, normals, colors and alpha which it will parse and return the results from.
  • Geom.Mesh.GenerateGridVerts is a new function that will generate a series of Vertex objects in a grid format, based on the given GenerateGridConfig config file. You can set the size of the grid, the number of segments to split it into, translate it, color it and tile the texture across it. The resulting data can be easily used by a Mesh Game Object.
  • Geom.Mesh.GenerateObjVerts is a new function that will generate a series of Vertex objects based on the given parsed Wavefront Obj Model data. You can optionally scale and translate the generated vertices and add them to a Mesh.
  • Geom.Mesh.ParseObj is a new function that will parse a triangulated Wavefront OBJ file into model data into a format that the GenerateObjVerts function can consume.
  • Geom.Mesh.ParseObjMaterial is a new function that will parse a Wavefront material file and extract the diffuse color data from it, combining it with the parsed object data.
  • Geom.Mesh.RotateFace is a new function that will rotate a Face by a given amount, based on an optional center of rotation.
  • Loader.OBJFile is a new File Loader type that can load triangulated Wavefront OBJ files, and optionally material files, which are then parsed and stored in the OBJ Cache.
  • The Mesh constructor and MeshFactory signatures have changed to scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first. indicies is a new parameter that allows you to provide indexed vertex data to create the Mesh from, where the indicies array holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. The indicies array is optional. If your data is not indexed, then simply pass null or an empty array for this parameter.
  • The Mesh Game Object now has the Animation State Component. This allows you to create and play animations across the texture of a Mesh, something that previously wasn't possible. As a result, the Mesh now adds itself to the Update List when added to a Scene.
  • Mesh.addVertices is a new method that allows you to add vertices to a Mesh Game Object based on the given parameters. This allows you to modify a mesh post-creation, or populate it with data at a later stage.
  • Mesh.addVerticesFromObj is a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the new OBJFile with a this.load.obj call, then you can use the key with this method. This method also takes an optional scale and position parameters to control placement of the created model within the Mesh.
  • Mesh.hideCCW is a new boolean property that, when enabled, tells a Face to not render if it isn't counter-clockwise. You can use this to hide backward facing Faces.
  • Mesh.modelPosition is a new Vector3 property that allows you to translate the position of all vertices in the Mesh.
  • Mesh.modelRotation is a new Vector3 property that allows you to rotate all vertices in the Mesh.
  • Mesh.modelScale is a new Vector3 property that allows you to scale all vertices in the Mesh.
  • Mesh.panX is a new function that will translate the view position of the Mesh on the x axis.
  • Mesh.panY is a new function that will translate the view position of the Mesh on the y axis.
  • Mesh.panZ is a new function that will translate the view position of the Mesh on the z axis.
  • Mesh.setPerspective is a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.
  • Mesh.setOrtho is a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.
  • Mesh.clear is a new method that will destroy all Faces and Vertices and clear the Mesh.
  • Mesh.depthSort is a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.
  • Mesh.addVertex is a new method that allows you to add a new single Vertex into the Mesh.
  • Mesh.addFace is a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.
  • Mesh.getFaceCount new is a new method that will return the total number of Faces in the Mesh.
  • Mesh.getVertexCount new is a new method that will return the total number of Vertices in the Mesh.
  • Mesh.getFace new is a new method that will return a Face instance from the Mesh based on the given index.
  • Mesh.getFaceAt new is a new method that will return an array of Face instances from the Mesh based on the given position. The position is checked against each Face, translated through the optional Camera and Mesh matrix. If more than one Face intersects, they will all be returned but the array will be depth sorted first, so the first element will be that closest to the camera.
  • Mesh.vertices is now an array of GameObject.Vertex instances, not a Float32Array.
  • Mesh.faces is a new array of GameObject.Face instances, which is populated during a call to methods like addVertices or addModel.
  • Mesh.totalRendered is a new property that holds the total number of Faces that were rendered in the previous frame.
  • Mesh.setDebug is a new method that allows you to render a debug visualisation of the Mesh vertices to a Graphics Game Object. You can provide your own Graphics instance and optionally callback that is invoked during rendering. This allows you to easily visualise the vertices of your Mesh to help debug UV mapping.
  • The Mesh now renders by iterating through the Faces array, not the vertices. This allows you to use Array methods such as BringToTop to reposition a Face, thus changing the drawing order without having to repopulate all of the vertices. Or, for a 3D model, you can now depth sort the Faces.
  • The Mesh Game Object now extends the SingleAlpha component and the alpha value is factored into the final alpha value per vertex during rendering. This means you can now set the whole alpha across the Mesh using the standard setAlpha methods. But, if you wish to, you can still control the alpha on a per-vertex basis as well.
  • The Mesh renderer will now check to see if the pipeline capacity has been exceeded for every Face added, allowing you to use Meshes with vertex counts that exceed the pipeline capacity without causing runtime errors.
  • You can now supply just a single numerical value as the colors parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the color for all vertices created.
  • You can now supply just a single numerical value as the alphas parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the alpha for all vertices created.
  • Mesh.debugGraphic is a new property that holds the debug Graphics instance reference.
  • Mesh.debugCallback is a new property that holds the debug render callback.
  • Mesh.renderDebugVerts is a new method that acts as the default render callback for setDebug if none is provided.
  • Mesh.preDestroy is a new method that will clean-up the Mesh arrays and debug references on destruction.
  • Mesh.isDirty is a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically in preUpdate to avoid generating lots of math when nothing has changed.
  • The Mesh.uv array has been removed. All UV data is now bound in the Vertex instances.
  • The Mesh.colors array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.alphas array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.tintFill property is now a boolean and defaults to false.

Quad Game Object Removed

The Quad Game Object has been removed from v3.50.0.

You can now create your own Quads easily using the new Geom.Mesh.GenerateGridVerts function, which is far more flexible than the old quads were.

Layer Game Object

A Layer is a special type of Game Object that acts as a Display List. You can add any type of Game Object to a Layer, just as you would to a Scene. Layers can be used to visually group together 'layers' of Game Objects:

```javascript const spaceman = this.add.sprite(150, 300, 'spaceman'); const bunny = this.add.sprite(400, 300, 'bunny'); const elephant = this.add.sprite(650, 300, 'elephant');

const layer = this.add.layer();

layer.add([ spaceman, bunny, elephant ]); ```

The 3 sprites in the example above will now be managed by the Layer they were added to. Therefore, if you then set layer.setVisible(false) they would all vanish from the display.

You can also control the depth of the Game Objects within the Layer. For example, calling the setDepth method of a child of a Layer will allow you to adjust the depth of that child within the Layer itself, rather than the whole Scene. The Layer, too, can have its depth set as well.

The Layer class also offers many different methods for manipulating the list, such as the methods moveUp, moveDown, sendToBack, bringToTop and so on. These allow you to change the display list position of the Layers children, causing it to adjust the order in which they are rendered. Using setDepth on a child allows you to override this.

Layers can have Post FX Pipelines set, which allows you to easily enable a post pipeline across a whole range of children, which, depending on the effect, can often be far more efficient that doing so on a per-child basis.

Layers have no position or size within the Scene. This means you cannot enable a Layer for physics or input, or change the position, rotation or scale of a Layer. They also have no scroll factor, texture, tint, origin, crop or bounds.

If you need those kind of features then you should use a Container instead. Containers can be added to Layers, but Layers cannot be added to Containers.

However, you can set the Alpha, Blend Mode, Depth, Mask and Visible state of a Layer. These settings will impact all children being rendered by the Layer.

Input / Mouse Updates and API Changes

  • ScaleManager.refresh is now called when the Game.READY event fires. This fixes a bug where the Scale Manager would have the incorrect canvas bounds, because they were calculated before a previous canvas was removed from the DOM. Fix #4862 (thanks @dranitski)
  • The Game Config property inputMouseCapture has been removed, as this is now split into 3 new config options:
  • inputMousePreventDefaultDown is a new config option that allows you to control preventDefault calls specifically on mouse down events. Set it via input.mouse.preventDefaultDown in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultUp is a new config option that allows you to control preventDefault calls specifically on mouse up events. Set it via input.mouse.preventDefaultUp in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultMove is a new config option that allows you to control preventDefault calls specifically on mouse move events. Set it via input.mouse.preventDefaultMove in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultWheel is a new config option that allows you to control preventDefault calls specifically on mouse wheel events. Set it via input.mouse.preventDefaultWheel in the Game Config. It defaults to true, the same as the previous capture property did.
  • The MouseManager.capture property has been removed, as this is now split into 3 new config options (see below)
  • MouseManager.preventDefaultDown is a new boolean property, set via the inputMousePreventDefaultDown config option that allows you to toggle capture of mouse down events at runtime.
  • MouseManager.preventDefaultUp is a new boolean property, set via the inputMousePreventDefaultUp config option that allows you to toggle capture of mouse up events at runtime.
  • MouseManager.preventDefaultMove is a new boolean property, set via the inputMousePreventDefaultMove config option that allows you to toggle capture of mouse move events at runtime.
  • MouseManager.preventDefaultWheel is a new boolean property, set via the inputMousePreventDefaultWheel config option that allows you to toggle capture of mouse wheel at runtime.
  • In the MouseManager the up, down and move events are no longer set as being passive if captured. Over, Out, Wheel and the Window level Down and Up events are always flagged as being passive. Wheel events are non-passive if capturing is enabled.
  • The GamepadPlugin will now call refreshPads as part of its start process. This allows you to use Gamepads across multiple Scenes, without having to wait for a connected event from each one of them. If you've already had a connected event in a previous Scene, you can now just read the pads directly via this.input.gamepad.pad1 and similar. Fix #4890 (thanks @Sytten)
  • Shutting down the Gamepad plugin (such as when sleeping a Scene) no longer calls GamepadPlugin.disconnectAll, but destroying it does.
  • Gamepad._created is a new private internal property that keeps track of when the instance was created. This is compared to the navigator timestamp in the update loop to avoid event spamming. Fix #4890.
  • Pointer.down will now check if the browser is running under macOS and if the ctrl key was also pressed, if so, it will flag the down event as being a right-click instead of a left-click, as per macOS conventions. Fix #4245 (thanks @BigZaphod)
  • When destroying an interactive Game Object that had useHandCursor enabled, it would reset the CSS cursor to default, even if the cursor wasn't over that Game Object. It will now only reset the cursor if it's over the Game Object being destroyed. Fix #5321 (thanks @JstnPwll)
  • The InputPlugin.shutdown method will now reset the CSS cursor, in case it was set by any Game Objects in the Scene that have since been destroyed.
  • The InputPlugin.processOverEvents has had a duplicate internal loop removed from it (thanks KingCosmic)

Tint Updates and Shader Changes

Phaser has had the ability to apply an additive tint to a Game Object since the beginning, and gained 'filled tints', with and without texture alpha, in v3.11. While this was handy, it introduced a 3-way if-else condition to the shaders to handle the different modes. Plus, setting tint colors was also generating rgb order Float32 color values for each Game Object, making reading those colors back again difficult (as they'd return in BGR order).

This has all changed in 3.50, as outlined below. Tint values are now used directly in the shader and don't pass through a color conversion function first. Lots of private properties have been removed and the shaders no longer have a 3-way if-else block. All of this means improved performance and a slight reduction in memory overhead.

  • Tint.tintTopLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTL which has now been removed.
  • Tint.tintTopRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTR which has now been removed.
  • Tint.tintBottomLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBL which has now been removed.
  • Tint.tintBottomRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBR which has now been removed.
  • The property Tint._isTinted has been removed as it's no longer required.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they now read the color value as outTint.bgr instead of outTint.rgb. This allows the colors to remain in RGB order within the Tint component.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they no longer have a 3-way check on the outTintEffect value.
  • The Multi Pipeline, Bitmap Text, Render Texture, Text, TileSprite and Camera now all read the tint values from the public properties instead of the private _tintTL etc ones. They also now set the tintEffect value directly from the tintFill property, removing another conditional check.
  • The function GetColorFromValue has been removed as it's no longer used internally.
  • The Rope.tintFill property is now a boolean, not an integer, and can no longer take 2 as a value for a complete fill. Instead, you should provide a solid color texture with no alpha.
  • As a result of the change to the shader, all uses of the WebGL Util function getTintAppendFloatAlphaAndSwap have been replaced with getTintAppendFloatAlpha instead.
  • As a result of the change to the shader, the Multi Pipeline now uses the WebGLRenderer.whiteTexture and tintEffect mode of 1 by default, instead of mode 2 (which has been removed) and a transparent texture. This ensures Graphics and Shapes objects still render correctly under the new smaller shader code.
  • WebGLRenderer.whiteTexture is a new property that is a reference to a pure white 4x4 texture that is created during Boot by the Texture Manager. The Graphics Pipeline uses this internally for all geometry fill rendering.
  • The TextureManager now generates a new texture with the key __WHITE durings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines.
  • Config.images.white is a new Game Config property that specifies the 4x4 white PNG texture used by Graphics rendering. You can override this via the config, but only do so if needed.

Arcade Physics Updates

Prior to v3.50 an Arcade Physics Body could be one of two states: immovable, or moveable. An immovable body could not receive any impact from another Body. If something collided with it, it wouldn't even separate to break free from the collision (the other body had to take the full separation value). It was intended for objects such as platforms, ground or walls, there they absolutely shouldn't move under any circumstances. As a result, two immovable bodies could never be collided together. While this worked for scenery-like items, it didn't work if you required maybe 2 players who could collide with each other, but should never be able to push one another. As of 3.50 all physics bodies now have a new property pushable that allows this. A pushable body can share separation with its collider, as well as take on mass-based velocity from the impact. A non-pushable body will behave differently depending on what it collides with. For example, a pushable body hitting a non-pushable (or immoveable) body will rebound off it.

  • The Arcade Physics Body class has a new boolean property pushable (true, by default). This allows you to set if a Body can be physically pushed by another Body, or not. Fix #4175 #4415 (thanks @inmylo @CipSoft-Components)
  • Body.setPushable is a new chainable method that allows you to set the pushable state of a Body.
  • Arcade.Components.Pushable is a new component, inherited by the standard Arcade Physics Image and Sprite classes.
  • Bodies will now check to see if they are blocked in the direction they're being pushed, before resolving the collision. This helps stop some bodies from being pushed into other objects.
  • Bodies will now check which direction they were moving and separate accordingly. This helps stop some bodies from being pushed into other objects.
  • ArcadePhysics.disableUpdate is a new method that will prevent the Arcade Physics World update method from being called when the Scene updates. By disabling it, you're free to call the update method yourself, passing in your own delta and time values.
  • ArcadePhysics.enableUpdate is a new method that will make the Arcade Physics World update in time with the Scene update. This is the default, so only call this if you have specifically disabled it previously.
  • ArcadeWorldConfig.customUpdate is a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. If true the World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)
  • Physics.Arcade.Body.setCollideWorldBounds now has a new optional parameter onWorldBounds which allows you to enable the Body's onWorldBounds property in the same call (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityX is a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityY is a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)
  • The PhysicsGroup config now has two new optional properties maxVelocityX and maxVelocityY which allows you to set the maximum velocity on bodies added to the Group (thanks @samme)
  • The Arcade.Body.resetFlags method has a new optional boolean parameter clear. If set, it clears the wasTouching flags on the Body. This happens automatically when Body.reset is called. Previous to this, the flags were not reset until the next physics step (thanks @samme)
  • Physics.Arcade.ProcessX is a new set of functions, called by the SeparateX function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Physics.Arcade.ProcessY is a new set of functions, called by the SeparateY function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Arcade.Body.center values were incorrect after collisions with the world bounds or (for rectangular bodies) after collisions with another body. The body center is now updated after those separations (thanks @samme)
  • The Arcade Physics WORLD_STEP event now has a new parameter: the delta argument (thanks @samme)
  • The Arcade Body drag property has been redefined when damping is used and scales the damping multiplier by the physics step delta. Drag is now the velocity retained after 1 second instead of after 1 step, when damping is used. This makes damping consistent for different physics step rates and more accurate when fixedStep is off. If you use drag you will need to change any existing drag values to get the same effects as before. Convert drag to drag ^ 60 or drag ^ fps if you use a different step rate (thanks @samme)

Loader Cache Changes

When loading any of the file types listed below it will no longer store the data file in the cache. For example, when loading a Texture Atlas using a JSON File, it used to store the parsed image data in the Texture Manager and also store the JSON in the JSON Cache under the same key. This has changed in 3.50. The data files are no longer cached, as they are not required by the textures once parsing is completed, which happens during load. This helps free-up memory. How much depends on the size of your data files. And also allows you to easily remove textures based on just their key, without also having to clear out the corresponding data cache.

  • AtlasJSONFile no longer stores the JSON in the JSON Cache once the texture has been created.
  • AtlasXMLFile no longer stores the XML in the XML Cache once the texture has been created.
  • UnityAtlasFile no longer stores the Text in the Text Cache once the texture has been created.
  • BitmapFontFile no longer stores the XML in the XML Cache once the texture has been created.
  • You can now use TextureManager.remove to remove a texture and not have to worry about clearing the corresponding JSON or XML cache entry as well in order to reload a new texture using the same key. Fix #5323 (thanks @TedGriggs)

ColorMatrix

  • Phaser.Display.ColorMatrix is a new class that allows you to create and manipulate a 5x4 color matrix, which can be used by shaders or graphics operations.
  • The ColorMatrix.set method allows you to set the values of a ColorMatrix.
  • The ColorMatrix.reset method will reset the ColorMatrix to its default values.
  • The ColorMatrix.getData method will return the data in the ColorMatrix as a Float32Array, useful for setting in a shader uniform.
  • The ColorMatrix.brightness method lets you set the brightness of the ColorMatrix.
  • The ColorMatrix.saturate method lets you set the saturation of the ColorMatrix.
  • The ColorMatrix.desaturate method lets you desaturate the colors in the ColorMatrix.
  • The ColorMatrix.hue method lets you rotate the hues of the ColorMatrix by the given amount.
  • The ColorMatrix.grayscale method converts the ColorMatrix to grayscale.
  • The ColorMatrix.blackWhite method converts the ColorMatrix to black and whites.
  • The ColorMatrix.contrast method lets you set the contrast of the ColorMatrix.
  • The ColorMatrix.negative method converts the ColorMatrix to negative values.
  • The ColorMatrix.desaturateLuminance method applies a desaturated luminance to the ColorMatrix.
  • The ColorMatrix.sepia method applies a sepia tone to the ColorMatrix.
  • The ColorMatrix.night method applies a night time effect to the ColorMatrix.
  • The ColorMatrix.lsd method applies a trippy color effect to the ColorMatrix.
  • The ColorMatrix.brown method applies a brown tone to the ColorMatrix.
  • The ColorMatrix.vintagePinhole method applies a vintage pinhole color effect to the ColorMatrix.
  • The ColorMatrix.kodachrome method applies a kodachrome color effect to the ColorMatrix.
  • The ColorMatrix.technicolor method applies a technicolor color effect to the ColorMatrix.
  • The ColorMatrix.polaroid method applies a polaroid color effect to the ColorMatrix.
  • The ColorMatrix.shiftToBGR method shifts the values of the ColorMatrix into BGR order.
  • The ColorMatrix.multiply method multiplies two ColorMatrix data sets together.

Removal of 'resolution' property from across the API

For legacy reasons, Phaser 3 has never properly supported HighDPI devices. It will render happily to them of course, but wouldn't let you set a 'resolution' for the Canvas beyond 1. Earlier versions of 3.x had a resolution property in the Game Config, but it was never fully implemented (for example, it would break zooming cameras). When the Scale Manager was introduced in v3.16 we forced the resolution to be 1 to avoid it breaking anything else internally.

For a long time, the 'resolution' property has been present - taunting developers and confusing new comers. In this release we have finally gone through and removed all references to it. The Game Config option is now gone, it's removed from the Scale Manager, Base Camera and everywhere else where it matters. As much as we would have liked to implement the feature, we've spent too long without it, and things have been built around the assumption it isn't present. The API just wouldn't cope with having it shoe-horned in at this stage. As frustrating as this is, it's even more annoying to just leave the property there confusing people and wasting CPU cycles. Phaser 4 has been built with HighDPI screens in mind from the very start, but it's too late for v3. The following changes are a result of this removal:

  • The Phaser.Scale.Events#RESIZE event no longer sends the resolution as a parameter.
  • The BaseCamera.resolution property has been removed.
  • The internal private BaseCamera._cx, _cy, _cw and _ch properties has been removed, use x, y, width and height instead.
  • The BaseCamera.preRender method no longer receives or uses the resolution parameter.
  • The Camera.preRender method no longer receives or uses the resolution parameter.
  • The CameraManager.onResize method no longer receives or uses the resolution parameter.
  • The Core.Config.resolution property has been removed.
  • The TextStyle.resolution property is no longer read from the Game Config. You can still set it via the Text Style config to a value other than 1, but it will default to this now.
  • The CanvasRenderer no longer reads or uses the Game Config resolution property.
  • The PipelineManager.resize method along with WebGLPipeline.resize and anything else that extends them no longer receives or uses the resolution parameter.
  • The WebGLRenderer.resize and onResize methods no longer receives or uses the resolution parameter.
  • The ScaleManager.resolution property has been removed and all internal use of it.

Removed 'interpolationPercentage' parameter from all render functions

Since v3.0.0 the Game Object render functions have received a parameter called interpolationPercentage that was never used. The renderers do not calculate this value and no Game Objects apply it, so for the sake of clairty, reducing code and removing complexity from the API it has been removed from every single function that either sent or expected the parameter. This touches every single Game Object and changes the parameter order as a result, so please be aware of this if you have your own custom Game Objects, or plugins, that implement their own render methods. In terms of surface API changes, you shouldn't notice anything at all from this removal.

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.
  • You can now use this.renderer from within a Scene, as it's now a Scene-level property and part of the Injection Map.
  • Clock.addEvent can now take an existing TimerEvent object, as well as a config object. If a TimerEvent is given it will be removed from the Clock, reset and then added. This allows you to pool TimerEvents rather than constantly create and delete them. Fix #4115 (thanks @jcyuan)
  • Clock.removeEvent is a new method that allows you to remove a TimerEvent, or an array of them, from all internal lists of the current Clock.
  • Group.getMatching is a new method that will return any members of the Group that match the given criteria, such as getMatching('visible', true) (thanks @atursams)
  • Utils.Array.SortByDigits is a new function that takes the given array of strings and runs a numeric sort on it, ignoring any non-digits.
  • GroupCreateConfig, which is used when calling Group.createMultiple or Group.createFromConfig, can now accept the following new properties: setOrigin: { x, y, stepX, stepY } which are applied to the items created by the Group.
  • Transform.copyPosition is a new method that will copy the position from the given object to the Game Object (thanks @samme)
  • The Text.MeasureText function, which is used to calculate the ascent and descent of Text Game Objects whenever the style, or font size, is changed, has been updated to use the new actualBoundingBoxAscent functions present in modern browsers. This allows for significantly faster ascent calculations than previously. Older browsers, such as IE, will still fall back (thanks @rexrainbow)
  • GameObjects.GetCalcMatrix is a new function that is used to calculate the transformed Game Object matrix, based on the given Game Object, Camera and Parent. This function is now used by the following Game Objects: BitmapText (Static and Dynamic), Graphics, Extern, Mesh, Rope, Shader, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. This dramatically reduces the amount of duplicate code across the API.
  • Utils.Array.Matrix.Translate is a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.
  • Vertor3.addScale is a new method that will add the given vector and multiply it in the process.
  • When defining the ease used with a Particle Emitter you can now set easeParams in the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh)
  • BitmapMask.createMask is a new method that will internally create the WebGL textures and framebuffers required for the mask. This is now used by the constructor and if the context is lost. It now also clears any previous textures/fbos that may have been created first, helping prevent memory leaks.
  • BitmapMask.clearMask will delete any WebGL textures or framebuffers the mask is using. This is now called when the mask is destroyed, or a new mask is created upon it.
  • Quaternion now has a new property onChangeCallback which, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.
  • The Quaternion.set method has a new optional boolean parameter update (defaults to true), which will call the onChangeCallback if set.
  • Quaternion.setFromEuler is a new method that will set the quaternion from the given Euler object, optionally calling the onChangeCallback in the process.
  • Quaternion.setFromRotationMatrix is a new method that will set the rotation of the quaternion from the given Matrix4.
  • Vector3.setFromMatrixPosition is a new method that will set the components of the Vector3 based on the position of the given Matrix4.
  • Vector3.setFromMatrixColumn is a new method that will set the components of the Vector3 based on the specified Matrix4 column.
  • Vector3.fromArray is a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.
  • Vector3.min is a new method that will set the components of the Vector3 based on the Main.min between it and the given Vector3.
  • Vector3.max is a new method that will set the components of the Vector3 based on the Main.max between it and the given Vector3.
  • Vector3.addVectors is a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.
  • Vector3.addScalar is a new method that will multiply the components of the Vector3 by the scale value given.
  • Vector3.applyMatrix3 is a new method that will take a Matrix3 and apply it to the Vector3.
  • Vector3.applyMatrix4 is a new method that will take a Matrix4 and apply it to the Vector3.
  • Vector3.projectViewMatrix is a new method that multiplies the Vector3 by the given view and projection matrices.
  • Vector3.unprojectViewMatrix is a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.
  • Matrix4.setValues is a new method that allows you to set all of the matrix components individually. Most internal methods now use this.
  • Matrix.multiplyToMat4 is a new method that multiplies a Matrix4 by the given src Matrix4 and stores the results in the out Matrix4.
  • Matrix4.fromRotationXYTranslation is a new method that takes the rotation and position vectors and builds this Matrix4 from them.
  • Matrix4.getMaxScaleOnAxis is a new method that will return the maximum axis scale from the Matrix4.
  • Matrix4.lookAtRH is a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.
  • Matrix4.transform is a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.
  • Matrix4.multiplyMatrices is a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.
  • Matrix4.premultiply is a new method that takes a Matrix4 and multiplies it by the current Matrix4.
  • Matrix4.getInverse is a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.
  • CameraManager.getVisibleChildren is a new method that is called internally by the CameraManager.render method. It filters the DisplayList, so that Game Objects that pass the willRender test for the given Camera are added to a sub-list, which is then passed to the renderer. This avoids the renderer having to do any checks on the children, it just renders each one in turn.
  • Physics.Arcade.Body.setDamping is a new method that allows you to set the useDamping property of a Body in a chainable way. Fix #5352 (thanks @juanitogan)
  • The GameObjects.Graphics.fillGradientStyle method can now accept a different alpha value for each of the fill colors. The default is still 1. If you only provide a single alpha, it'll be used for all colors. Fix #5044 (thanks @zhangciwu)
  • Types.Core.PipelineConfig is a new configuration object that you can set in the Game Config under the pipeline property. It allows you to define custom WebGL pipelines as part of the Game Config, so they're automatically installed and ready for use by all Scenes in your game. You can either set the pipeline object, or set it under the render sub-config.
  • Utils.Object.DeepCopy is a new function that will recursively deep copy an array of object.
  • Time.TimerEvent.getRemaining is a new method that returns the time interval until the next iteration of the Timer Event (thanks @samme)
  • Time.TimerEvent.getRemainingSeconds is a new method that returns the time interval until the next iteration of the Timer Event in seconds (thanks @samme)
  • Time.TimerEvent.getOverallRemaining is a new method that returns the time interval until the last iteration of the Timer Event (thanks @samme)
  • Time.TimerEvent.getOverallRemainingSeconds is a new method that returns the time interval until the last iteration of the Timer Event in seconds (thanks @samme)
  • GameObjects.Video.loadMediaStream is a new method that allows you to hook a Video Game Object up to a Media Stream, rather than a URL, allowing you to stream video from a source such as a webcam (thanks @pirateksh)
  • Display.Color.ColorSpectrum is a new function that will return an array of 1024 Color Object elements aligned in a Color Spectrum layout, where the darkest colors have been omitted.
  • AsepriteFile is a new File Type for the Loader that allows you to load Aseprite images and animation data for use with the new Aseprite animation features. You can call this via this.load.asesprite(png, json).
  • GameObject.displayList is a new property that contains a reference to the Display List to which the Game Object has been added. This will typically either by the Display List owned by a Scene, or a Layer Game Object. You should treat this property as read-only.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Earcut has now been exposed and is available via Geom.Polygon.Earcut and is fully documented.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.
  • Pointer.downTime now stores the event timestamp of when the first button on the input device was pressed down, not just when button 1 was pressed down.
  • Pointer.upTime now stores the event timestamp of when the final depressed button on the input device was released, not just when button 1 was released.
  • The Pointer.getDuration method now uses the new Pointer downTime and upTime values, meaning it will accurately report the duration of when any button is being held down, not just the primary one. Fix #5112 (thanks @veleek)
  • The BaseShader default vertex shader now includes the outTexCoord vec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok)
  • When using the GameObjectCreator for Containers you can now specify the children property in the configuration object.
  • Textures.Parsers.JSONHash will now perform a hasOwnProperty check when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes from JSON.parse. Fix #4768 (thanks @RollinSafary)
  • The Camera3D Plugin has been rebuilt for Phaser 3.50 and the webpack config updated. This plugin is now considered deprecated and will not be updated beyond this release.
  • Tween.seek will no longer issue a console warning for 'Tween.seek duration too long', it's now up to you to check on the performance of tween seeking.
  • If inputWindowEvents is set in the Game Config, then the MouseManager will now listen for the events on window.top instead of just window, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in a try/catch block, as not all sites allow access to window.top (specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow)
  • MouseManager.isTop is a new boolean read-only property that flags if the mouse event listeners were attached to window.top (true), or just window (false). By default Phaser will attempt window.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back to window in those cases and set this property to false (thanks BunBunBun)
  • Types.GameObjects.Text.GetTextSizeObject is a new type def for the GetTextSize function results.
  • Utils.Array.StableSort has been recoded. It's now based on Two-Screens stable sort 0.1.8 and has been updated to fit into Phaser better and no longer create any window bound objects. The inplace function has been removed, just call StableSort(array) directly now. All classes that used StableSort.inplace have been updated to call it directly.
  • If a Scene is paused, or sent to sleep, it will automatically call Keyboard.resetKeys. This means that if you hold a key down, then sleep or pause a Scene, then release the key and resume or wake the Scene, it will no longer think it is still being held down (thanks @samme)
  • Actions.setOrigin will now call updateDisplayOrigin on the items array, otherwise the effects can't be seen when rendering.
  • You can now set the ArcadeWorld.fixedStep property via the ArcadeWorldConfig object (thanks @samme)
  • Utils.Array.NumerArray can now accept the start and end parameters in reverse order, i.e. 10, 1 will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.
  • DataManager.Events.DESTROY is a new event that the Data Manager will listen for from its parent and then call its own destroy method when received.
  • The Quaternion class constructor will now default the values to 0,0,0,1 if they're not provided, making it an identity quaternion, rather than the 0,0,0,0 it was before.
  • You can now set the ParticleEmitter.reserve value via the emitter configuration object (thanks @vforsh)
  • Setting the pixelArt config option will now set antialiasGL to false, as well as antialias. Fix #5309 (thanks @Vegita2)
  • The Shape class now includes the ComputedSize component properties and methods directly in the class, rather than applying as a mixin. setSize is now flagged as being private, because it shouldn't be used on Shape classes, which was leading to confusion as it appeared in the public-facing API. Fix #4811 (thanks @aolsx)
  • The Loader.maxParallelDownloads value is now set to 6 if running on Android, or 32 on any other OS. This avoids net::ERR_FAILED issues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary)
  • When running an Arcade Physics overlap test against a StaticBody, it will no longer set the blocked states of the dynamic body. If you are doing a collision test, they will still be set, but they're skipped for overlap-only tests. Fix #4435 (thanks @samme)
  • The Line Game Object will now default its width and height to 1, rather than zero. This allows you to give Line objects a physics body (although you will still need to re-adjust the center of the body manually). Fix #4596 (thanks @andrewaustin)
  • Internally, the Quaternion class now has 4 new private properties: _x, _y, _z and _w and 4 new getters and setters for the public versions. It also now passes most methods via set to allow for the onChange callback to be invoked. This does not change the public-facing API.
  • Group now extends EventEmitter, allowing you to emit custom events from within a Group.
  • Device.Audio.wav now uses audio/wav as the canPlayType check string, instead of audio/wav; codecs="1", which should allow iOS13 to play wav files again.
  • In the Loader.FileTypes.TextFile config you can now override the type and cache destination for the file.
  • Loader.MultiFile will now parse the given files array and only add valid entries into the file list, allowing multifiles to now have optional file entries.
  • The ParticleEmitter.tint value is now 0xffffff (previously, it was 0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh)
  • SceneManager.start will now reset the SceneSystems.sceneUpdate reference to NOOP. This gets set back to the Scene update method again during bootScene (if it has one) and stops errors with external plugins and multi-part files that may trigger update before create has been called. Fix #4629 (thanks @Osmose)
  • Phaser.Scene.renderer is a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.
  • The CanvasRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.
  • Since iOS 13, iPads now identify as MacOS devices. A new maxTouchPoint check is now part of the Device.OS tests, stopping iPads from being flagged as desktop devices. Fix #5389 (thanks @SBCGames)
  • The BitmapMask.prevFramebuffer property has been removed as it's no longer required, due to the fbo stack in the renderer.
  • The TextureManager.addGLTexture method has been updated so that the width and height parameters are now optional. If not provided, and if available, they will be read from the given WebGLTexture instead (thanks @hexus)
  • GameObjects.Components.Depth.depthList is a new property that all Game Objects that have the Depth Component now have. It contains a reference to the List responsible for managing the depth sorting of the Game Object. This is typically the Scene Display List, but can also be a Layer. It allows the Depth component to queue a depth sort directly on the list it belongs to now, rather than just the Scene.

Bug Fixes

  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)
  • The GridAlign action didn't work if only the height parameter was set. Fix #5019 (thanks @halilcakar)
  • The Color.HSVToRGB function has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX)
  • Previously, the easeParams array within a Tweens props object, or a multi-object tween, were ignored and it was only used if set on the root Tween object. It will now work correctly set at any depth. Fix #4292 (thanks @willblackmore)
  • When using Camera.setRenderToTexture its zoom and rotation values would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok)
  • GameObjects.Shape.Grid would render a white fill even if you passed undefined as the fill color in the constructor. It now doesn't render cells if no fill color is given.
  • The onMouse events in the Input Manager didn't reset the activePointer property to the mouse, meaning on dual-input systems such as Touch Screen devices, the active pointer would become locked to whichever input method was used first. Fix #4615 #5232 (thanks @mmolina01 @JstnPwll @Legomite)
  • The Scale Managers GetScreenOrientation function will now check for window.orientation first, because iOS mobile browsers have an incomplete implementation of the Screen API, forcing us to use the window value as a priority. This means the Scale Manager will now emit orientationchange events correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu)
  • Time.Clock.addEvent can now take an instance of a TimerEvent as its parameter. Fix #5294 (thanks @samme @EmilSV)
  • GameConfig.audio now defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)
  • The Loader.path was being added to the File URL even if the URL was absolute. This is now checked for and the path is not applied unless the URL is relative (thanks @firesoft)
  • Group.getMatching would always return an empty array. It now returns matching children (thanks @samme)
  • The ParticleManagerWebGLRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in follow offsets separately. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers. Fix #5319 #5195 #4739 #4691 (thanks @vforsh @condeagustin @IvanDem @Formic)
  • The ParticleManagerCanvasRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also uses setToContext internally. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers, or having the Camera zoomed, running under Canvas. Fix #4908 #4531 #4131 (thanks @smjnab @SirLink @jhooper04)
  • The Graphics WebGL Renderer will now default to pathOpen = true. This fixes issues under WebGL where, for example, adding an arc and calling strokePath, without first calling beginPath will no longer cause rendering artefacts when WebGL tries to close the path with a single tri.
  • Graphics.strokeRoundedRect now issues moveTo commands as part of the drawing sequence, preventing issues under WebGL where on older Android devices it would project additional vertices into the display. Fix #3955 (thanks @alexeymolchan)
  • Creating a Bitmap Mask from a texture atlas that was then used to mask another Game Object also using that same texture atlas would throw the error GL_INVALID_OPERATION : glDrawArrays: Source and destination textures of the draw are the same.. It now renders as expected. Fix #4675 (thanks @JacobCaron)
  • When using the same asset for a Game Object to be used as a mask, it would make other Game Objects using the same asset, that appeared above the mask in the display list, to not render. Fix #4767 (thanks @smjnab)
  • When taking a snapshot in WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in the WebGLSnapshot function. Fix #4956 (thanks @gammafp @telinc1)
  • Particles.EmitterOp.setMethods will now reset both onEmit and onUpdate to their default values. This allows you to reconfigure an emitter op with a new type of value and not have it stuck on the previous one. Fix #3663 (thanks @samme)
  • Particles.EmitterOp now cleanly separates between the different types of property configuration options. start | end will now ease between the two values, min | max will pick a random value between them and random: [] will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)
  • When setting both transparent: true and backgroundColor in the Game Config, it would ignore the transparency and use the color anyway. If transparent, the game is now fully transparent. Fix #5362 (thanks @Hoshinokoe)
  • The Ellipse Game Object now will update the width, height, and geometric position in the setSize method (thanks @PhaserEditor2D)
  • When measuring the last word in a line in a Text Game Object, it no longer adds extra white space to the end (thanks @rexrainbow)
  • Utils.Array.Remove would return an incorrect array of removed elements if one of the items to be removed was skipped in the array. Fix #5398 (thanks @year221)
  • Geom.Intersects.TriangleToLine wouldn't return true if the start or end of the Line fell inside the Triangle, only if the entire Line did. It now checks the start and end points correctly. (thanks @wiserim)
  • Using a Bitmap Mask and a Blend Mode in WebGL would reset the blend mode when the mask was rendered, causing the Game Object to have no blend mode. Fix #5409 (thanks @jcyuan)
  • BitmapMask would become corrupted when resizing the Phaser Game, either via the Scale Manager or directly, because the framebuffer and texture it used for rendering was still at the old dimensions. The BitmapMask now listens for the Renderer RESIZE event and re-creates itself accordingly. Fix #5399 (thanks @Patapits)

Namespace Updates

  • The Phaser.Curves.MoveTo function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.DOM.GetInnerHeight function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Bob class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsManager class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsPlugin class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Particles.EmitterOp class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.GetTextSize function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.MeasureText function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.TextStyle function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Input.CreatePixelPerfectHandler function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapCirc function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapRect function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Tilemap namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Components namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.MatterGameObject class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.PointerConstraint class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetPhysicsPlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetScenePlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Structs.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Tilemaps.Parsers.Tiled function has now been exposed on the Phaser namespace (thanks @samme)
  • Every single Tilemap.Component function has now been made public. This means you can call the Component functions directly, should you need to, outside of the Tilemap system.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360 @volkans80 @jaabberwocky @maikthomas @atursams @LearningCode2023 @DylanC @BenjaminDRichards @rexrainbow @Riderrr @spwilson2 @EmilSV @PhaserEditor2D @Gangryong @vinerz @trynx @usufruct99 @pirateksh @justin-calleja @monteiz

- JavaScript
Published by photonstorm over 5 years ago

phaser - Phaser v3.50.0 Beta 11

Version 3.50.0 - Subaru - in development

WebGL Pipeline Updates

If you use a custom WebGL Pipeline in your game, you must update your code in order to use Phaser 3.50.

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

There is also the new GraphicsPipeline. Previously, the TextureTintPipeline was responsible for rendering all Sprites, Graphics and Shape objects. Now, it only renders Sprites. All Graphics and Shapes are handled by the new GraphicsPipeline which uses its own shaders. See further below for details about this change.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

Other pipeline changes are as follows:

  • None of the shaders or pipelines use the uViewMatrix and uModelMatrix uniforms any longer. These were always just plain identity matrices, so there is no point spending CPU and GPU time to set them as uniforms, or use them in the shaders. Should you need these uniforms, you can add them to your own custom pipelines.
  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.
  • The WebGLPipeline.shouldFlush method now accepts an optional parameter amount. If given, it will return true if when the amount is added to the vertex count it will exceed the vertex capacity. The Multi Pipeline has been updated to now use this method instead of performing the comparison multiple times itself.
  • The RopePipeline now extends MultiPipeline and just changes the topolgy, vastly reducing the filesize.
  • The WebGLPipeline.flushLocked property has been removed. A pipeline can never flush in the middle of a flush anyway, so it was just wasting CPU cycles being set.
  • You can now pass a pipeline instance to the GameObject.setPipeline method, as well as a string.

Pipeline Uniform Changes

Piplines now have a new uniforms array that can be passed in with the config. All default pipelines now set these. The array contains the names, as strings, of all uniforms your pipeline shader uses. Once the pipeline shader has been successfully linked, it will use the array of names to look-up the WebGLUniformLocation of all uniforms specified. These are stored in the new WebGLPipeline.uniforms object. This takes place in the new WebGLPipeline.setUniformLocations method.

When a pipeline is bound, you can now use the new methods (listed below) to set uniform values directly on the pipeline. Previously, calling a method such as setFloat3 on a pipeline would pass that call over to WebGLRenderer. The renderer would first check to see if the pipeline program was current, and if not, make it so, before then looking up the uniform location and finally setting it. This is a lot of steps to take for pipelines that potentially need to change uniforms for every Game Object they render.

Under the new methods, and using the new pre-cached uniform locations, these extra steps are skipped. The uniform value is set directly, no shader binding takes place and no location look-up happens. This dramatically reduces the number of WebGL ops being issued per frame. To clearly differentiate these pipline methods, we have renamed them. The new method names are as follows:

  • WebGLPipeline.set1f will set a 1f uniform based on the given name.
  • WebGLPipeline.set2f will set a 2f uniform based on the given name.
  • WebGLPipeline.set3f will set a 3f uniform based on the given name.
  • WebGLPipeline.set4f will set a 4f uniform based on the given name.
  • WebGLPipeline.set1fv will set a 1fv uniform based on the given name.
  • WebGLPipeline.set2fv will set a 2fv uniform based on the given name.
  • WebGLPipeline.set3fv will set a 3fv uniform based on the given name.
  • WebGLPipeline.set4fv will set a 4fv uniform based on the given name.
  • WebGLPipeline.set1iv will set a 1iv uniform based on the given name.
  • WebGLPipeline.set2iv will set a 2iv uniform based on the given name.
  • WebGLPipeline.set3iv will set a 3iv uniform based on the given name.
  • WebGLPipeline.set4iv will set a 4iv uniform based on the given name.
  • WebGLPipeline.set1i will set a 1i uniform based on the given name.
  • WebGLPipeline.set2i will set a 2i uniform based on the given name.
  • WebGLPipeline.set3i will set a 3i uniform based on the given name.
  • WebGLPipeline.set4i will set a 4i uniform based on the given name.
  • WebGLPipeline.setMatrix2fv will set a matrix 2fv uniform based on the given name.
  • WebGLPipeline.setMatrix3fv will set a matrix 3fv uniform based on the given name.
  • WebGLPipeline.setMatrix4fv will set a matrix 4fv uniform based on the given name.

If your code uses any of the old method names, please update them using the list below:

  • WebGLPipeline.setFloat1 has been removed. Please use set1f instead.
  • WebGLPipeline.setFloat2 has been removed. Please use set2f instead.
  • WebGLPipeline.setFloat3 has been removed. Please use set3f instead.
  • WebGLPipeline.setFloat4 has been removed. Please use set4f instead.
  • WebGLPipeline.setFloat1v has been removed. Please use set1fv instead.
  • WebGLPipeline.setFloat2v has been removed. Please use set2fv instead.
  • WebGLPipeline.setFloat3v has been removed. Please use set3fv instead.
  • WebGLPipeline.setFloat4v has been removed. Please use set4fv instead.
  • WebGLPipeline.setInt1 has been removed. Please use set1i instead.
  • WebGLPipeline.setInt2 has been removed. Please use set2i instead.
  • WebGLPipeline.setInt3 has been removed. Please use set3i instead.
  • WebGLPipeline.setInt4 has been removed. Please use set4i instead.
  • WebGLPipeline.setMatrix1 has been removed. Please use setMatrix2fv instead.
  • WebGLPipeline.setMatrix2 has been removed. Please use setMatrix3fv instead.
  • WebGLPipeline.setMatrix3 has been removed. Please use setMatrix4fv instead.

Pipeline Manager

The WebGL.PipelineManager is a new class that is responsbile for managing all of the WebGL Pipelines in Phaser. An instance of the Pipeline Manager is created by the WebGL Renderer and is available under the pipelines property. This means that the WebGL Renderer no longer handles pipelines directly, causing the following API changes:

  • WebGLRenderer.pipelines is no longer a plain object containing pipeline instances. It's now an instance of the PipelineManager class. This instance is created during the init and boot phase of the renderer.
  • The WebGLRenderer.currentPipeline property no longer exists, instead use PipelineManager.current.
  • The WebGLRenderer.previousPipeline property no longer exists, instead use PipelineManager.previous.
  • The WebGLRenderer.hasPipeline method no longer exists, instead use PipelineManager.has.
  • The WebGLRenderer.getPipeline method no longer exists, instead use PipelineManager.get.
  • The WebGLRenderer.removePipeline method no longer exists, instead use PipelineManager.remove.
  • The WebGLRenderer.addPipeline method no longer exists, instead use PipelineManager.add.
  • The WebGLRenderer.setPipeline method no longer exists, instead use PipelineManager.set.
  • The WebGLRenderer.rebindPipeline method no longer exists, instead use PipelineManager.rebind.
  • The WebGLRenderer.clearPipeline method no longer exists, instead use PipelineManager.clear.

The Pipeline Manager also offers the following new features:

  • The PipelineManager.resize method automatically handles resize events across all pipelines.
  • The PipelineManager.preRender method calls the pre-render method of all pipelines.
  • The PipelineManager.render method calls the render method of all pipelines.
  • The PipelineManager.postRender method calls the post-render method of all pipelines.
  • The PipelineManager.setMulti method automatically binds the Multi Texture Pipeline, Phaser's default.
  • The PipelineManager.clear method will clear the pipeline, store it in previous and free the renderer.
  • The PipelineManager.rebind method will reset the rendering context and restore the previous pipeline, if set.

New constants have been created to help you reference a pipeline without needing to use strings:

  • Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE for the Bitmap Mask Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE for the Light 2D Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE for the Single Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE for the Multi Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE for the Rope Pipeline.

All Game Objects have been updated to use the new constants and Pipeline Manager.

Single Pipeline

There is also a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGL Multi-Texture Rendering

The Multi Pipeline (previously called the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw-call bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLPipeline.forceZero is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.
  • The WebGL.Utils.getComponentCount function has been removed as this is no longer required internally.

WebGLRenderer New Features, Updates and API Changes

  • WebGLRenderer.instancedArraysExtension is a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.
  • WebGLRenderer.vaoExtension is a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.
  • WebGLRenderer.resetProgram is a new method that will rebind the current program, without flushing or changing any properties.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • WebGLRenderer.finalType is a new boolean property that signifies if the current Game Object being rendered is the final one in the list.
  • The WebGLRenderer.updateCanvasTexture method will now set gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL to true, which should stop issues where you update a Text Game Object, having added a Render Texture or Spine Game Object to the Scene after it, which switches the PMA setting. Fix #5064 #5155 (thanks @hugoruscitti @immangrove-supertree)
  • WebGLRenderer.previousPipeline is a new property that is set during a call to clearPipeline and used during calls to rebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.
  • The WebGLRenderer.rebindPipeline method has been changed slightly. Previously, you had to specify the pipelineInstance, but this is now optional. If you don't, it will use the new previousPipeline property instead. If not set, or none given, it will now return without throwing gl errors as well.
  • WebGLRenderer.defaultScissor is a new property that holds the default scissor dimensions for the renderer. This is modified during resize and avoids continuous array generation in the preRender loop.
  • The WebGLRenderer.nativeTextures array has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in the TextureSource objects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy.
  • The WebGLRenderer.deleteTexture method has a new optional boolean parameter reset which allows you to control if the WebGLRenderer.resetTextures method is called, or not, after the texture is deleted.
  • The WebGLRenderer.getMaxTextures method has been removed. This is no longer needed as you can use the WebGLRenderer.maxTextures property instead.
  • The WebGLRenderer.setProgram method now returns a boolean. true if the program was set, otherwise false.
  • The WebGLRenderer.setVertexBuffer method now returns a boolean. true if the buffer was set, otherwise false.
  • WebGLRenderer.setFloat1 has been removed. Use WebGLPipeline.set1f or WebGLShader.set1f instead.
  • WebGLRenderer.setFloat2 has been removed. Use WebGLPipeline.set2f or WebGLShader.set2f instead.
  • WebGLRenderer.setFloat3 has been removed. Use WebGLPipeline.set3f or WebGLShader.set3f instead.
  • WebGLRenderer.setFloat4 has been removed. Use WebGLPipeline.set4f or WebGLShader.set4f instead.
  • WebGLRenderer.setFloat1v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set1fv instead.
  • WebGLRenderer.setFloat2v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set2fv instead.
  • WebGLRenderer.setFloat3v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set3fv instead.
  • WebGLRenderer.setFloat4v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set4fv instead.
  • WebGLRenderer.setInt1 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set1i instead.
  • WebGLRenderer.setInt2 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set2i instead.
  • WebGLRenderer.setInt3 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set3i instead.
  • WebGLRenderer.setInt4 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set4i instead.
  • WebGLRenderer.setMatrix2 has been removed. Use WebGLPipeline.setMatrix2fv or WebGLShader.setMatrix2fv instead.
  • WebGLRenderer.setMatrix3 has been removed. Use WebGLPipeline.setMatrix3fv or WebGLShader.setMatrix3fv instead.
  • WebGLRenderer.setMatrix4 has been removed. Use WebGLPipeline.setMatrix4fv or WebGLShader.setMatrix4fv instead.
  • The WebGLRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.
  • WebGLRenderer.fboStack is a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.
  • WebGLRenderer.pushFramebuffer is a new method that is used to push a framebuffer onto the fbo stack before setting it as the current framebuffer. This should now be called in place of setFramebuffer. Remember to call popFramebuffer after using it.
  • WebGLRenderer.popFramebuffer is a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.
  • WebGLRenderer.setFramebuffer has a new optional boolean parameter resetTextures which will reset the WebGL Textures, if set to true (which is the default).
  • WebGLRenderer.isBooted is a new boolean property that lets you know if the rendere has fully finished booting.
  • The WebGLRenderer now extends the Event Emitter, allowing you to listen to renderer specific events.
  • Phaser.Renderer.WebGL.Events is a new WebGL Renderer namespace for events.
  • WebGL.Events.PRE_RENDER is a new event dispatched by the WebGL Renderer. This happens right at the start of the render process.
  • WebGL.Events.RENDER is a new event dispatched by the WebGL Renderer. This happens once for every camera, in every Scene at the start of its render process.
  • WebGL.Events.POST_RENDER is a new event dispatched by the WebGL Renderer. This happens right at the end of the render process.
  • WebGL.Events.RESIZE is a new event dispatched by the WebGL Renderer whenever it is resized.

Camera - New Features, Updates and API Changes

The Camera API has changed in line with the new pipeline updates. To this end, the following changes have taken place:

The Camera class now inherits the Pipeline Component. This gives it new features, in line with the other pipelines changes in 3.50, such as Camera.setPipeline, Camera.setPostPipeline, Camera.setPipelineData and so on. This is a much more powerful and flexible way of setting camera effects, rather than it managing its own framebuffer and texture directly.

To that end, the following properties and methods have been removed to tidy things up:

  • The Camera.renderToTexture property has been removed. Effects are now handled via pipelines.
  • The Camera.renderToGame property has been removed. Effects are now handled via pipelines.
  • The Camera.canvas property has been removed. Textures are handled by pipelines.
  • The Camera.context property has been removed. Textures are handled by pipelines.
  • The Camera.glTexture property has been removed. GL Textures are handled by pipelines.
  • The Camera.framebuffer property has been removed. GL Framebuffers are handled by pipelines.
  • The Camera.setRenderToTexture method has been removed. Effects are now handled via pipelines.
  • The Camera.clearRenderToTexture method has been removed. Effects are now handled via pipelines.

These changes mean that you can no longer render a Camera to a canvas in Canvas games.

Other changes and fixes:

  • Camera.zoomX is a new property that allows you to specifically set the horizontal zoom factor of a Camera.
  • Camera.zoomY is a new property that allows you to specifically set the vertical zoom factor of a Camera.
  • The Camera.setZoom method now allows you to pass two parameters: x and y, to control the zoomX and zoomY values accordingly.
  • The Camera.zoom property now returns an average of the zoomX and zoomY properties.
  • Cameras.Scene2D.Events.FOLLOW_UPDATE is a new Event that is dispatched by a Camera when it is following a Game Object. It is dispatched every frame, right after the final Camera position and internal matrices have been updated. Use it if you need to react to a camera, using its most current position and the camera is following something. Fix #5253 (thanks @rexrainbow)
  • If the Camera has roundPixels set it will now round the internal scroll factors and worldView during the preRender step. Fix #4464 (thanks @Antriel)

Graphics Pipeline and Graphics Game Object Changes

The Graphics Pipeline is a new pipeline added in 3.50 that is responsible for rendering Graphics Game Objects and all of the Shape Game Objects, such as Arc, Rectangle, Star, etc. Due to the new pipeline some changes have been made:

  • The Graphics Pipeline now uses much simpler vertex and fragment shaders, with just two attributes (inPosition and inColor), making the vertex size and memory-use 57% smaller.
  • The private _tempMatrix1, 2, 3 and 4 properties have all been removed from the pipeline.
  • A new public calcMatrix property has been added, which Shape Game Objects use to maintain transform state during rendering.
  • The Graphics Pipeline no longer makes use of tintEffect or any textures.
  • Because Graphics and Shapes now render with their own pipeline, you are able to exclude the pipeline and those Game Objects entirely from custom builds, further reducing the final bundle size.

As a result of these changes the following features are no longer available:

  • Graphics.setTexture has been removed. You can no longer use a texture as a 'fill' for a Graphic. It never worked with any shape other than a Rectangle, anyway, due to UV mapping issues, so is much better handled via the new Mesh Game Object.
  • Graphics._tempMatrix1, 2 and 3 have been removed. They're not required internally any longer.
  • Graphics.renderWebGL now uses the standard GetCalcMatrix function, cutting down on duplicate code significantly.

Render Texture Game Object Changes

The Render Texture Game Object has been rewritten to use the new RenderTarget class internally, rather than managing its own framebuffer and gl textures directly. The core draw methods are now a lot simpler and no longer require manipulating render pipelines.

As a result of these changes the follow updates have happened:

  • RenderTexture.renderTarget is a new property that contains a RenderTarget instance, which is used for all drawing.
  • The RenderTexture.framebuffer property has been removed. You can now access this via RenderTexture.renderTarget.framebuffer.
  • The RenderTexture.glTexture property has been removed. You can now access this via RenderTexture.renderTarget.texture.
  • The RenderTexture.gl property has been removed.

Light Pipeline Changes

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh and Quad Game Objects now support rendering with normal maps.
  • The Graphics Game Objects now support rendering in Light2d. You can even use normal map textures for the texture fills.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • All Shape Game Objects (Rectangle, IsoBox, Star, Polygon, etc) now support rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Both Static and Dynamic Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Lights

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

WebGL ModelViewProjection Removed

The ModelViewProjection object contained a lot of functions that Phaser never used internally. Instead, the functions available in them were already available in the Math.Matrix4 class. So the pipelines have been updated to use a Matrix4 instead and all of the MVP functions have been removed. The full list of removed functions is below:

  • projIdentity has been removed.
  • projPersp has been removed.
  • modelRotateX has been removed.
  • modelRotateY has been removed.
  • modelRotateZ has been removed.
  • viewLoad has been removed.
  • viewRotateX has been removed.
  • viewRotateY has been removed.
  • viewRotateZ has been removed.
  • viewScale has been removed.
  • viewTranslate has been removed.
  • modelIdentity has been removed.
  • modelScale has been removed.
  • modelTranslate has been removed.
  • viewIdentity has been removed.
  • viewLoad2D has been removed.
  • projOrtho has been removed.

BitmapText - New Features, Updates and API Changes

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has to work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.
  • You can now use setMaxWidth on DynamicBitmapText, which wasn't previously possible. Fix #4997 (thanks @AndreaBoeAbrahamsen)

Update List Changes

The way in which Game Objects add themselves to the Scene Update List has changed. Instead of being added by the Factory methods, they will now add and remove themselves based on the new ADDED_TO_SCENE and REMOVED_FROM_SCENE events. This means, you can now add Sprites directly to a Container, or Group, and they'll animate properly without first having to be part of the Update List. The full set of changes and new features relating to this follow:

  • GameObjects.Events.ADDED_TO_SCENE is a new event, emitted by a Game Object, when it is added to a Scene, or a Container that is part of the Scene.
  • GameObjects.Events.REMOVED_FROM_SCENE is a new event, emitted by a Game Object, when it is removed from a Scene, or a Container that is part of the Scene.
  • Scenes.Events.ADDED_TO_SCENE is a new event, emitted by a Scene, when a new Game Object is added to the display list in the Scene, or a Container that is on the display list.
  • Scenes.Events.REMOVED_FROM_SCENE is a new event, emitted by a Scene, when it a Game Object is removed from the display list in the Scene, or a Container that is on the display list.
  • GameObject.addedToScene is a new method that custom Game Objects can use to perform additional set-up when a Game Object is added to a Scene. For example, Sprite uses this to add itself to the Update List.
  • GameObject.removedFromScene is a new method that custom Game Objects can use to perform additional tear-down when a Game Object is removed from a Scene. For example, Sprite uses this to remove themselves from the Update List.
  • Game Objects no longer automatically remove themselves from the Update List during preDestroy. This should be handled directly in the removedFromScene method now.
  • The Container will now test to see if any Game Object added to it is already on the display list, or not, and emit its ADDED and REMOVED events accordingly. Fix #5267 #3876 (thanks @halgorithm @mbpictures)
  • DisplayList.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • DisplayList.addChildCallback is a new method that overrides the List callback and fires the new ADDED events.
  • DisplayList.removeChildCallback is a new method that overrides the List callback and fires the new REMOVED events.
  • GameObjectCreator.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • GameObjectFactory.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • ProcessQueue.checkQueue is a new boolean property that will make sure only unique objects are added to the Process Queue.
  • The Update List now uses the new checkQueue property to ensure no duplicate objects are on the active list.
  • DOMElementFactory, ExternFactory, ParticleManagerFactor, RopeFactory and SpriteFactory all no longer add the objects to the Update List, this is now handled by the ADDED events instead.
  • Sprite, Rope, ParticleEmitterManager, Extern and DOMElement now all override the addedToScene and removedFromScene callbacks to handle further set-up tasks.

Spine Plugin Updates

  • The Spine Runtimes have been updated to 3.8.99, which are the most recent non-beta versions. Please note, you will need to re-export your animations if you're working in a version of Spine lower than 3.8.20.
  • SpineContainer is a new Game Object available via this.add.spineContainer to which you can add Spine Game Objects only. It uses a special rendering function to retain batching, even across multiple container or Spine Game Object instances, resulting in dramatically improved performance compared to using regular Containers. You can still use regular Containers if you need, but they do not benefit from the new batching.
  • A Spine Game Object with setVisible(false) will no longer still cause internal gl commands and is now properly skipped, retaining any current batch in the process. Fix #5174 (thanks @Kitsee)
  • The Spine Game Object WebGL Renderer will no longer clear the type if invisible and will only end the batch if the next type doesn't match.
  • The Spine Game Object WebGL Renderer will no longer rebind the pipeline if it was the final object on the display list, saving lots of gl commands.
  • The Webpack build scripts have all been updated for Webpack 4.44.x. Fix #5243 (thanks @RollinSafary)
  • There is a new npm script npm run plugin.spine.runtimes which will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo into plugins/spine/ in order for this to work and then run npm i.
  • Spine Game Objects can now be rendered to Render Textures. Fix #5184 (thanks @Kitsee)
  • Using > 128 Spine objects in a Container would cause a WebGL: INVALID_OPERATION: vertexAttribPointer: no ARRAY_BUFFER is bound and offset is non-zero error if you added any subsequent Spine objects to the Scene. There is now no limit. Fix #5246 (thanks @d7561985)
  • The Spine Plugin will now work in HEADLESS mode without crashing. Fix #4988 (thanks @raimon-segura)
  • Spine Game Objects now use -1 as their default blend mode, which means 'skip setting it', as blend modes should be handled by the Spine skeletons directly.
  • The Spine TypeScript defs have been updated for the latest version of the plugin and to add SpineContainers.
  • The SpineGameObject.setAnimation method will now use the trackIndex parameter if ignoreIfPlaying is set and run the check against this track index. Fix #4842 (thanks @vinerz)
  • The SpineFile will no longer throw a warning if adding a texture into the Texture Manager that already exists. This allows you to have multiple Spine JSON use the same texture file, however, it also means you now get no warning if you accidentally load a texture that exists, so be careful with your keys! Fix #4947 (thanks @Nomy1)
  • The Spine Plugin destroy method will now no longer remove the Game Objects from the Game Object Factory, or dispose of the Scene Renderer. This means when a Scene is destroyed, it will keep the Game Objects in the factory for other Scenes to use. Fix #5279 (thanks @Racoonacoon)
  • SpinePlugin.gameDestroy is a new method that is called if the Game instance emits a destroy event. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.
  • SpineFile will now check to see if another identical atlas in the load queue is already loading the texture it needs and will no longer get locked waiting for a file that will never complete. This allows multiple skeleton JSONs to use the same atlas data. Fix #5331 (thanks @Racoonacoon)
  • SpineFile now uses a ! character to split the keys, instead of an underscore, preventing the plugin from incorrectly working out the keys for filenames with underscores in them. Fix #5336 (thanks @Racoonacoon)
  • SpineGameObject.willRender is no longer hard-coded to return true. It instead now takes a Camera parameter and performs all of the checks needed before returning. Previously, this happened during the render functions.
  • The Spine Plugin now uses a single instance of the Scene Renderer when running under WebGL. All instances of the plugin (installed per Scene) share the same base Scene Renderer, avoiding duplicate allocations and resizing events under multi-Scene games. Fix #5286 (thanks @spayton BunBunBun)

Animation API - New Features and Updates

If you use Animations in your game, please read the following important API changes in 3.50:

The Animation API has had a significant overhaul to improve playback handling. Instead of just playing an animation based on its global key, you can now supply a new PlayAnimationConfig object instead, which allows you to override any of the default animation settings, such as duration, delay and yoyo (see below for the full list). This means you no longer have to create lots of duplicate animations just to change properties such as duration, and can now set them dynamically at run-time as well.

  • The Animation class no longer extends EventEmitter, as it no longer emits any events directly. This means you cannot now listen for events directly from an Animation instance. All of the events are now dispatched by the Game Objects instead.
  • All of the SPRITE_ANIMATION_KEY events have been removed. Instead, please use the new events which all carry the frameKey parameter, which can be used to handle frame specific events. The only exception to this is ANIMATION_COMPLETE_KEY, which is a key specific version of the completion event.
  • ANIMATION_UPDATE_EVENT is a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.
  • ANIMATION_STOP_EVENT is a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of the stop methods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)
  • The Game Object Component.Animation component has been renamed to AnimationState and has moved namespace. It's now in Phaser.Animations instead of GameObjects.Components to help differentiate it from the Animation class when browsing the documentation.
  • The play, playReverse, playAfterDelay, playAfterRepeat and chain Sprite and Animation Component methods can now all take a Phaser.Types.Animations.PlayAnimationConfig configuration object, as well as a string, as the key parameter. This allows you to override any default animation setting with those defined in the config, giving you far greater control over animations on a Game Object level, without needing to globally duplicate them.
  • AnimationState.create is a new method that allows you to create animations directly on a Sprite. These are not global and never enter the Animation Manager, instead risiding within the Sprite itself. This allows you to use the same keys across both local and global animations and set-up Sprite specific local animations.
  • AnimationState.generateFrameNumbers is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • AnimationState.generateFrameNames is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • All playback methods: play, playReverse, playAfterDelay and playAfterRepeat will now check to see if the given animation key exists locally on the Sprite first. If it does, it's used, otherwise it then checks the global Animation Manager for the key instead.
  • AnimationState.skipMissedFrames is now used when playing an animation, allowing you to create animations that run at frame rates far exceeding the refresh rate, or that will update to the correct frame should the game lag. Feature #4232 (thanks @colorcube)
  • AnimationManager.addMix is a new method that allows you to create mixes 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.
  • AnimationManager.getMix is a new method that will return the mix duration between the two given animations.
  • AnimationManager.removeMix is a new method that will remove the mixture between either two animations, or all mixtures for the given animation.
  • AnimationState.remove is a new method that will remove a locally stored Animation instance from a Sprite.
  • AnimationState.get is a new method that will return a locally stored Animation instance from the Sprite.
  • AnimationState.exists is a new method that will check if a locally stored Animation exists on the Sprite.
  • The internal AnimationState.remove method has been renamed to globalRemove.
  • AnimationState.textureManager is a new property that references the global Texture Manager.
  • AnimationState.anims is a new property that contains locally created Animations in a Custom Map.
  • AnimationState.play and Sprite.play no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • AnimationState.playReverse and Sprite.playReverse no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • The AnimationState.delayedPlay method has been renamed to playAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration.
  • The AnimationState.stopOnRepeat method has been renamed to stopAfterRepeat
  • The AnimationState.getCurrentKey method has been renamed to getName.
  • AnimationState.getFrameName is a new method that will return the key of the current Animation Frame, if an animation has been loaded.
  • AnimationState.playAfterDelay and Sprite.playAfterDelay are new methods that will play the given animation after the delay in ms expires.
  • AnimationState.playAfterRepeat and Sprite.playAfterRepeat are new methods that will play the given animation after the current animation finishes repeating. You can also specify the number of repeats allowed left to run.
  • The AnimationState.chain method is now available on the Sprite class.
  • The AnimationState.stopAfterDelay method is now available on the Sprite class.
  • The AnimationState.stopAfterRepeat method is now available on the Sprite class.
  • The AnimationState.stopOnFrame method is now available on the Sprite class.
  • AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser. Please see the comprehensive documentation for this method for full details on how to do this.
  • AnimationState now handles all of the loading of the animation. It no longer has to make calls out to the Animation Manager or Animation instance itself and will load the animation data directly, replacing as required from the optional PlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.
  • The PlayAnimationConfig.frameRate property lets you optionally override the animation frame rate.
  • The PlayAnimationConfig.duration property lets you optionally override the animation duration.
  • The PlayAnimationConfig.delay property lets you optionally override the animation delay.
  • The PlayAnimationConfig.repeat property lets you optionally override the animation repeat counter.
  • The PlayAnimationConfig.repeatDelay property lets you optionally override the animation repeat delay value.
  • The PlayAnimationConfig.yoyo property lets you optionally override the animation yoyo boolean.
  • The PlayAnimationConfig.showOnStart property lets you optionally override the animation show on start value.
  • The PlayAnimationConfig.hideOnComplete property lets you optionally override the animation hide on complete value.
  • The PlayAnimationConfig.startFrame property lets you optionally set the animation frame to start on.
  • The PlayAnimationConfig.timeScale property lets you optionally set the animation time scale factor.
  • AnimationState.delayCounter is a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animation START events fire. Fix #4426 (thanks @bdaenen)
  • AnimationState.hasStarted is a new boolean property that allows you to tell if the current animation has started playing, or is still waiting for a delay to expire.
  • AnimationState.showOnStart is a new boolean property that controls if the Game Object should have setVisible(true) called on it when the animation starts.
  • AnimationState.hideOnComplete is a new boolean property that controls if the Game Object should have setVisible(false) called on it when the animation completes.
  • The AnimationState.chain method docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does!
  • The AnimationState.setDelay method has been removed. It never actually worked and you can now perform the same thing by calling either playAfterDelay or setting the delay property in the play config.
  • The AnimationState.getDelay method has been removed. You can now read the delay property directly.
  • The AnimationState.setRepeat method has been removed. You can achieve the same thing by setting the repeat property in the play config, or adjusting the public repeatCounter property if the animation has started.
  • AnimationState.handleStart is a new internal private method that handles the animation start process.
  • AnimationState.handleRepeat is a new internal private method that handles the animation repeat process.
  • AnimationState.handleStop is a new internal private method that handles the animation stop process.
  • AnimationState.handleComplete is a new internal private method that handles the animation complete process.
  • AnimationState.emitEvents is a new internal private method that emits animation events, cutting down on duplicate code.
  • The AnimationState.restart method has a new optional boolean parameter resetRepeats which controls if you want to reset the repeat counter during the restart, or not.
  • Animation.getTotalFrames is a new method that will return the total number of frames in the animation. You can access it via this.anims.currentAnim.getTotalFrames from a Sprite.
  • Animation.calculateDuration is a new method that calculates the duration, frameRate and msPerFrame for a given animation target.
  • The BuildGameObjectAnimation function now uses the PlayAnimationConfig object to set the values.
  • Sprite.playReverse is a new method that allows you to play the given animation in reverse on the Sprite.
  • Sprite.playAfterDelay is a new method that allows you to play the given animation on the Sprite after a delay.
  • Sprite.stop is a new method that allows you to stop the current animation on the Sprite.
  • AnimationManager.load has been removed as it's no longer required.
  • AnimationManager.staggerPlay has been fixed so you can now pass in negative stagger values.
  • AnimationManager.staggerPlay has a new optional boolean parameter staggerFirst, which allows you to either include or exclude the first child in the stagger calculations.
  • The Animation.completeAnimation method has been removed as it's no longer required.
  • The Animation.load method has been removed as it's no longer required.
  • The Animation.setFrame method has been removed as it's no longer required.
  • The Animation.getFirstTick method has no longer needs the includeDelay parameter, as it's handled by AnimationState now.
  • The Animation.getFrames method has a new optional boolean parameter sortFrames which will run a numeric sort on the frame names after constructing them, if a string-based frame is given.
  • Types.Animations.Animation has a new boolean property sortFrames, which lets Phaser numerically sort the generated frames.
  • AnimationState.timeScale is a new public property that replaces the old private _timeScale property.
  • AnimationState.delay is a new public property that replaces the old private _delay property.
  • AnimationState.repeat is a new public property that replaces the old private _repeat property.
  • AnimationState.repeatDelay is a new public property that replaces the old private _repeatDelay property.
  • AnimationState.yoyo is a new public property that replaces the old private _yoyo property.
  • AnimationState.inReverse is a new public property that replaces the old private _reverse property.
  • AnimationState.startAnimation is a new public method that replaces the old private _startAnimation method.
  • The AnimationState.getProgress method has been fixed so it will return correctly if the animation is playing in reverse.
  • The AnimationState.globalRemove method will now always be called when an animation is removed from the global Animation Manager, not just once.
  • The AnimationState.getRepeat method has now been removed. You can get the value from the repeat property.
  • The AnimationState.setRepeatDelay method has now been removed. You can set the value using the repeatDelay config property, or changing it at run-time.
  • AnimationState.complete is a new method that handles the completion in animation playback.
  • The AnimationState.setTimeScale method has now been removed. You can set the value using the timeScale config property, or changing it at run-time.
  • The AnimationState.getTimeScale method has now been removed. You can read the value using the timeScale property.
  • The AnimationState.getTotalFrames method has been fixed and won't error if called when no animation is loaded.
  • The AnimationState.setYoyo method has now been removed. You can set the value using the yoyo config property, or changing it at run-time.
  • The AnimationState.getYoyo method has now been removed. You can read the value using the yoyo property.
  • The AnimationState.stopAfterRepeat method now has an optional parameter repeatCount, so you can tell the animation to stop after a specified number of repeats, not just 1.
  • When playing an animation in reverse, if it reached the first frame and had to repeat, it would then jump to the frame before the final frame and carry on, skipping out the final frame.
  • The AnimationState.updateFrame method has now been removed. Everything is handled by setCurrentFrame instead, which removes one extra step out of the update process.
  • GenerateFrameNames will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers would include the __BASE frame by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.
  • GenerateFrameNumbers can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.
  • GenerateFrameNames can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.

Tilemap - New Features, Updates and API Changes

There are three large changes to Tilemaps in 3.50. If you use tilemaps, you must read this section:

1) The first change is that there are no longer DynamicTilemapLayer and StaticTilemapLayer classes. They have both been removed and replaced with the new TilemapLayer class. This new class consolidates features from both and provides a lot cleaner API experience, as well as speeding up internal logic.

In your game where you use map.createDynamicLayer or map.createStaticLayer replace it with map.createLayer instead.

2) The second change is that the Tilemap system now supports isometric, hexagonal and staggered isometric map types, along with the previous orthogonal format, thanks to a PR from @svipal. You can now export maps using any of these orientations from the Tiled Map Editor and load them into Phaser using the existing tilemap loading API. No further changes need to take place in the way your maps are loaded.

3) The Tilemap.createFromObjects method has been overhauled to make it much more useful. The method signature has changed and it now takes a new CreateFromObjectLayerConfig configuration object, or an array of them, which allows much more fine-grained control over which objects in the Tiled Object Layers are converted and what they are converted to. Previously it could only convert to Sprites, but you can now pass in a custom class, filter based on id, gid or name, even provide a Container to add the created Game Objects to. Please see the new documentation for this method and the config object for more details. Fix #3817 #4613 (thanks @georgzoeller @Secretmapper)

  • The Tilemap.createDynamicLayer method has been renamed to createLayer.
  • The Tilemap.createStaticLayer method has been removed. Use createLayer instead.
  • The Tilemap.createBlankDynamicLayer method has been renamed to createBlankLayer.
  • The Tilemap.convertLayerToStatic method has been removed as it is no longer required.
  • The TilemapLayerWebGLRenderer function will no longer iterate through the layer tilesets, drawing tiles from only that set. Instead all it does now is iterate directly through only the tiles. This allows it to take advantage of the new Multi Texturing pipeline and also draw multi-tileset isometric layers correctly.
  • Phaser.Types.Tilemaps.TilemapOrientationType is a new type def that holds the 4 types of map orientation now supported.
  • The Tile.updatePixelXY method now updates the tile XY position based on map type.
  • ParseTilesets will now correctly handle non-consecutive tile IDs. It also now correctly sets the maxId property, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)
  • Tilemap.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • LayerData.orientation is a new property that holds the tilemap layers orientation constant.
  • LayerData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • MapData.orientation is a new property that holds the tilemap layers orientation constant.
  • MapData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • Tilemaps.Components.HexagonalWorldToTileY is a new function that converts a world Y coordinate to hexagonal tile Y coordinate.
  • Tilemaps.Components.StaggeredWorldToTileY is a new function that converts a world Y coordinate to staggered tile Y coordinate.
  • Tilemaps.Components.HexagonalWorldToTileXY is a new function that converts world coordinates to hexagonal tile coordinates.
  • Tilemaps.Components.IsometricWorldToTileXY is a new function that converts world coordinates to isometric tile coordinates.
  • Tilemaps.Components.StaggeredWorldToTileXY is a new function that converts world coordinates to staggered tile coordinates.
  • Tilemaps.Components.HexagonalTileToWorldY is a new function that converts a hexagonal Y coordinate to a world coordinate.
  • Tilemaps.Components.StaggeredTileToWorldY is a new function that converts a staggered Y coordinate to a world coordinate.
  • Tilemaps.Components.HexagonalTileToWorldXY is a new function that converts hexagonal tile coordinates to world coordinates.
  • Tilemaps.Components.IsometricTileToWorldXY is a new function that converts isometric tile coordinates to world coordinates.
  • Tilemaps.Components.StaggeredTileToWorldXY is a new function that converts staggered tile coordinates to world coordinates.
  • Tilemaps.Components.GetTileToWorldXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldXXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetCullTilesFunction is a new function that returns the correct culling function to use.
  • Tilemaps.Components.HexagonalCullTiles is a new function that culls tiles in a hexagonal map.
  • Tilemaps.Components.StaggeredCullTiles is a new function that culls tiles in a staggered map.
  • Tilemaps.Components.IsometricCullTiles is a new function that culls tiles in a isometric map.
  • Tilemaps.Components.CullBounds is a new function that calculates the cull bounds for an orthogonal map.
  • Tilemaps.Components.HexagonalCullBounds is a new function that calculates the cull bounds for a hexagonal map.
  • Tilemaps.Components.StaggeredCullBounds is a new function that calculates the cull bounds for a staggered map.
  • Tilemaps.Components.RunCull is a new function that runs the culling process from the combined bounds and tilemap.
  • Tilemap._convert is a new internal private hash of tilemap conversion functions used by the public API.
  • The Tilemap._isStaticCall method has been removed and no Tilemap methods now check this, leading to faster execution.
  • The Arcade Physics Sprites vs. Tilemap Layers flow has changed. Previously, it would iterate through a whole bunch of linked functions, taking lots of jumps in the process. It now just calls the GetTilesWithinWorldXY component directly, saving lots of overhead.
  • The method Tilemap.weightedRandomize has changed so that the parameter weightedIndexes is now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional.
  • The method TilemapLayer.weightedRandomize has changed so that the parameter weightedIndexes is now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional.

Mesh Game Object - New Features, Updates and API Changes

The Mesh Game Object has been rewritten from scratch in v3.50 with a lot of changes to make it much more useful. It is accompanied by the new Geom.Mesh set of functions.

  • Geom.Mesh is a new namespace that contains the Mesh related geometry functions. These are stand-alone functions that you may, or may not require, depending on your game.
  • Geom.Mesh.Vertex is a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.
  • Geom.Mesh.Face is a new class that consists of references to the three Vertex instances that construct a single Face in a Mesh and provides methods for manipulating them.
  • Geom.Mesh.GenerateVerts is a new function that will return an array of Vertex and Face objects generated from the given data. You can provide index, or non-index vertex lists, along with UV data, normals, colors and alpha which it will parse and return the results from.
  • Geom.Mesh.GenerateGridVerts is a new function that will generate a series of Vertex objects in a grid format, based on the given GenerateGridConfig config file. You can set the size of the grid, the number of segments to split it into, translate it, color it and tile the texture across it. The resulting data can be easily used by a Mesh Game Object.
  • Geom.Mesh.GenerateObjVerts is a new function that will generate a series of Vertex objects based on the given parsed Wavefront Obj Model data. You can optionally scale and translate the generated vertices and add them to a Mesh.
  • Geom.Mesh.ParseObj is a new function that will parse a triangulated Wavefront OBJ file into model data into a format that the GenerateObjVerts function can consume.
  • Geom.Mesh.ParseObjMaterial is a new function that will parse a Wavefront material file and extract the diffuse color data from it, combining it with the parsed object data.
  • Geom.Mesh.RotateFace is a new function that will rotate a Face by a given amount, based on an optional center of rotation.
  • Loader.OBJFile is a new File Loader type that can load triangulated Wavefront OBJ files, and optionally material files, which are then parsed and stored in the OBJ Cache.
  • The Mesh constructor and MeshFactory signatures have changed to scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first. indicies is a new parameter that allows you to provide indexed vertex data to create the Mesh from, where the indicies array holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. The indicies array is optional. If your data is not indexed, then simply pass null or an empty array for this parameter.
  • The Mesh Game Object now has the Animation State Component. This allows you to create and play animations across the texture of a Mesh, something that previously wasn't possible. As a result, the Mesh now adds itself to the Update List when added to a Scene.
  • Mesh.addVertices is a new method that allows you to add vertices to a Mesh Game Object based on the given parameters. This allows you to modify a mesh post-creation, or populate it with data at a later stage.
  • Mesh.addVerticesFromObj is a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the new OBJFile with a this.load.obj call, then you can use the key with this method. This method also takes an optional scale and position parameters to control placement of the created model within the Mesh.
  • Mesh.hideCCW is a new boolean property that, when enabled, tells a Face to not render if it isn't counter-clockwise. You can use this to hide backward facing Faces.
  • Mesh.modelPosition is a new Vector3 property that allows you to translate the position of all vertices in the Mesh.
  • Mesh.modelRotation is a new Vector3 property that allows you to rotate all vertices in the Mesh.
  • Mesh.modelScale is a new Vector3 property that allows you to scale all vertices in the Mesh.
  • Mesh.panX is a new function that will translate the view position of the Mesh on the x axis.
  • Mesh.panY is a new function that will translate the view position of the Mesh on the y axis.
  • Mesh.panZ is a new function that will translate the view position of the Mesh on the z axis.
  • Mesh.setPerspective is a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.
  • Mesh.setOrtho is a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.
  • Mesh.clear is a new method that will destroy all Faces and Vertices and clear the Mesh.
  • Mesh.depthSort is a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.
  • Mesh.addVertex is a new method that allows you to add a new single Vertex into the Mesh.
  • Mesh.addFace is a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.
  • Mesh.getFaceCount new is a new method that will return the total number of Faces in the Mesh.
  • Mesh.getVertexCount new is a new method that will return the total number of Vertices in the Mesh.
  • Mesh.getFace new is a new method that will return a Face instance from the Mesh based on the given index.
  • Mesh.getFaceAt new is a new method that will return an array of Face instances from the Mesh based on the given position. The position is checked against each Face, translated through the optional Camera and Mesh matrix. If more than one Face intersects, they will all be returned but the array will be depth sorted first, so the first element will be that closest to the camera.
  • Mesh.vertices is now an array of GameObject.Vertex instances, not a Float32Array.
  • Mesh.faces is a new array of GameObject.Face instances, which is populated during a call to methods like addVertices or addModel.
  • Mesh.totalRendered is a new property that holds the total number of Faces that were rendered in the previous frame.
  • Mesh.setDebug is a new method that allows you to render a debug visualisation of the Mesh vertices to a Graphics Game Object. You can provide your own Graphics instance and optionally callback that is invoked during rendering. This allows you to easily visualise the vertices of your Mesh to help debug UV mapping.
  • The Mesh now renders by iterating through the Faces array, not the vertices. This allows you to use Array methods such as BringToTop to reposition a Face, thus changing the drawing order without having to repopulate all of the vertices. Or, for a 3D model, you can now depth sort the Faces.
  • The Mesh Game Object now extends the SingleAlpha component and the alpha value is factored into the final alpha value per vertex during rendering. This means you can now set the whole alpha across the Mesh using the standard setAlpha methods. But, if you wish to, you can still control the alpha on a per-vertex basis as well.
  • The Mesh renderer will now check to see if the pipeline capacity has been exceeded for every Face added, allowing you to use Meshes with vertex counts that exceed the pipeline capacity without causing runtime errors.
  • You can now supply just a single numerical value as the colors parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the color for all vertices created.
  • You can now supply just a single numerical value as the alphas parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the alpha for all vertices created.
  • Mesh.debugGraphic is a new property that holds the debug Graphics instance reference.
  • Mesh.debugCallback is a new property that holds the debug render callback.
  • Mesh.renderDebugVerts is a new method that acts as the default render callback for setDebug if none is provided.
  • Mesh.preDestroy is a new method that will clean-up the Mesh arrays and debug references on destruction.
  • Mesh.isDirty is a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically in preUpdate to avoid generating lots of math when nothing has changed.
  • The Mesh.uv array has been removed. All UV data is now bound in the Vertex instances.
  • The Mesh.colors array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.alphas array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.tintFill property is now a boolean and defaults to false.

Quad Game Object Removed

The Quad Game Object has been removed from v3.50.0.

You can now create your own Quads easily using the new Geom.Mesh.GenerateGridVerts function, which is far more flexible than the old quads were.

Layer Game Object

A Layer is a special type of Game Object that acts as a Display List. You can add any type of Game Object to a Layer, just as you would to a Scene. Layers can be used to visually group together 'layers' of Game Objects:

```javascript const spaceman = this.add.sprite(150, 300, 'spaceman'); const bunny = this.add.sprite(400, 300, 'bunny'); const elephant = this.add.sprite(650, 300, 'elephant');

const layer = this.add.layer();

layer.add([ spaceman, bunny, elephant ]); ```

The 3 sprites in the example above will now be managed by the Layer they were added to. Therefore, if you then set layer.setVisible(false) they would all vanish from the display.

You can also control the depth of the Game Objects within the Layer. For example, calling the setDepth method of a child of a Layer will allow you to adjust the depth of that child within the Layer itself, rather than the whole Scene. The Layer, too, can have its depth set as well.

The Layer class also offers many different methods for manipulating the list, such as the methods moveUp, moveDown, sendToBack, bringToTop and so on. These allow you to change the display list position of the Layers children, causing it to adjust the order in which they are rendered. Using setDepth on a child allows you to override this.

Layers can have Post FX Pipelines set, which allows you to easily enable a post pipeline across a whole range of children, which, depending on the effect, can often be far more efficient that doing so on a per-child basis.

Layers have no position or size within the Scene. This means you cannot enable a Layer for physics or input, or change the position, rotation or scale of a Layer. They also have no scroll factor, texture, tint, origin, crop or bounds.

If you need those kind of features then you should use a Container instead. Containers can be added to Layers, but Layers cannot be added to Containers.

However, you can set the Alpha, Blend Mode, Depth, Mask and Visible state of a Layer. These settings will impact all children being rendered by the Layer.

Input / Mouse Updates and API Changes

  • ScaleManager.refresh is now called when the Game.READY event fires. This fixes a bug where the Scale Manager would have the incorrect canvas bounds, because they were calculated before a previous canvas was removed from the DOM. Fix #4862 (thanks @dranitski)
  • The Game Config property inputMouseCapture has been removed, as this is now split into 3 new config options:
  • inputMousePreventDefaultDown is a new config option that allows you to control preventDefault calls specifically on mouse down events. Set it via input.mouse.preventDefaultDown in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultUp is a new config option that allows you to control preventDefault calls specifically on mouse up events. Set it via input.mouse.preventDefaultUp in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultMove is a new config option that allows you to control preventDefault calls specifically on mouse move events. Set it via input.mouse.preventDefaultMove in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultWheel is a new config option that allows you to control preventDefault calls specifically on mouse wheel events. Set it via input.mouse.preventDefaultWheel in the Game Config. It defaults to true, the same as the previous capture property did.
  • The MouseManager.capture property has been removed, as this is now split into 3 new config options (see below)
  • MouseManager.preventDefaultDown is a new boolean property, set via the inputMousePreventDefaultDown config option that allows you to toggle capture of mouse down events at runtime.
  • MouseManager.preventDefaultUp is a new boolean property, set via the inputMousePreventDefaultUp config option that allows you to toggle capture of mouse up events at runtime.
  • MouseManager.preventDefaultMove is a new boolean property, set via the inputMousePreventDefaultMove config option that allows you to toggle capture of mouse move events at runtime.
  • MouseManager.preventDefaultWheel is a new boolean property, set via the inputMousePreventDefaultWheel config option that allows you to toggle capture of mouse wheel at runtime.
  • In the MouseManager the up, down and move events are no longer set as being passive if captured. Over, Out, Wheel and the Window level Down and Up events are always flagged as being passive. Wheel events are non-passive if capturing is enabled.
  • The GamepadPlugin will now call refreshPads as part of its start process. This allows you to use Gamepads across multiple Scenes, without having to wait for a connected event from each one of them. If you've already had a connected event in a previous Scene, you can now just read the pads directly via this.input.gamepad.pad1 and similar. Fix #4890 (thanks @Sytten)
  • Shutting down the Gamepad plugin (such as when sleeping a Scene) no longer calls GamepadPlugin.disconnectAll, but destroying it does.
  • Gamepad._created is a new private internal property that keeps track of when the instance was created. This is compared to the navigator timestamp in the update loop to avoid event spamming. Fix #4890.
  • Pointer.down will now check if the browser is running under macOS and if the ctrl key was also pressed, if so, it will flag the down event as being a right-click instead of a left-click, as per macOS conventions. Fix #4245 (thanks @BigZaphod)
  • When destroying an interactive Game Object that had useHandCursor enabled, it would reset the CSS cursor to default, even if the cursor wasn't over that Game Object. It will now only reset the cursor if it's over the Game Object being destroyed. Fix #5321 (thanks @JstnPwll)
  • The InputPlugin.shutdown method will now reset the CSS cursor, in case it was set by any Game Objects in the Scene that have since been destroyed.
  • The InputPlugin.processOverEvents has had a duplicate internal loop removed from it (thanks KingCosmic)

Tint Updates and Shader Changes

Phaser has had the ability to apply an additive tint to a Game Object since the beginning, and gained 'filled tints', with and without texture alpha, in v3.11. While this was handy, it introduced a 3-way if-else condition to the shaders to handle the different modes. Plus, setting tint colors was also generating rgb order Float32 color values for each Game Object, making reading those colors back again difficult (as they'd return in BGR order).

This has all changed in 3.50, as outlined below. Tint values are now used directly in the shader and don't pass through a color conversion function first. Lots of private properties have been removed and the shaders no longer have a 3-way if-else block. All of this means improved performance and a slight reduction in memory overhead.

  • Tint.tintTopLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTL which has now been removed.
  • Tint.tintTopRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTR which has now been removed.
  • Tint.tintBottomLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBL which has now been removed.
  • Tint.tintBottomRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBR which has now been removed.
  • The property Tint._isTinted has been removed as it's no longer required.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they now read the color value as outTint.bgr instead of outTint.rgb. This allows the colors to remain in RGB order within the Tint component.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they no longer have a 3-way check on the outTintEffect value.
  • The Multi Pipeline, Bitmap Text, Render Texture, Text, TileSprite and Camera now all read the tint values from the public properties instead of the private _tintTL etc ones. They also now set the tintEffect value directly from the tintFill property, removing another conditional check.
  • The function GetColorFromValue has been removed as it's no longer used internally.
  • The Rope.tintFill property is now a boolean, not an integer, and can no longer take 2 as a value for a complete fill. Instead, you should provide a solid color texture with no alpha.
  • As a result of the change to the shader, all uses of the WebGL Util function getTintAppendFloatAlphaAndSwap have been replaced with getTintAppendFloatAlpha instead.
  • As a result of the change to the shader, the Multi Pipeline now uses the WebGLRenderer.whiteTexture and tintEffect mode of 1 by default, instead of mode 2 (which has been removed) and a transparent texture. This ensures Graphics and Shapes objects still render correctly under the new smaller shader code.
  • WebGLRenderer.whiteTexture is a new property that is a reference to a pure white 4x4 texture that is created during Boot by the Texture Manager. The Graphics Pipeline uses this internally for all geometry fill rendering.
  • The TextureManager now generates a new texture with the key __WHITE durings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines.
  • Config.images.white is a new Game Config property that specifies the 4x4 white PNG texture used by Graphics rendering. You can override this via the config, but only do so if needed.

Arcade Physics Updates

Prior to v3.50 an Arcade Physics Body could be one of two states: immovable, or moveable. An immovable body could not receive any impact from another Body. If something collided with it, it wouldn't even separate to break free from the collision (the other body had to take the full separation value). It was intended for objects such as platforms, ground or walls, there they absolutely shouldn't move under any circumstances. As a result, two immovable bodies could never be collided together. While this worked for scenery-like items, it didn't work if you required maybe 2 players who could collide with each other, but should never be able to push one another. As of 3.50 all physics bodies now have a new property pushable that allows this. A pushable body can share separation with its collider, as well as take on mass-based velocity from the impact. A non-pushable body will behave differently depending on what it collides with. For example, a pushable body hitting a non-pushable (or immoveable) body will rebound off it.

  • The Arcade Physics Body class has a new boolean property pushable (true, by default). This allows you to set if a Body can be physically pushed by another Body, or not. Fix #4175 #4415 (thanks @inmylo @CipSoft-Components)
  • Body.setPushable is a new chainable method that allows you to set the pushable state of a Body.
  • Arcade.Components.Pushable is a new component, inherited by the standard Arcade Physics Image and Sprite classes.
  • Bodies will now check to see if they are blocked in the direction they're being pushed, before resolving the collision. This helps stop some bodies from being pushed into other objects.
  • Bodies will now check which direction they were moving and separate accordingly. This helps stop some bodies from being pushed into other objects.
  • ArcadePhysics.disableUpdate is a new method that will prevent the Arcade Physics World update method from being called when the Scene updates. By disabling it, you're free to call the update method yourself, passing in your own delta and time values.
  • ArcadePhysics.enableUpdate is a new method that will make the Arcade Physics World update in time with the Scene update. This is the default, so only call this if you have specifically disabled it previously.
  • ArcadeWorldConfig.customUpdate is a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. If true the World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)
  • Physics.Arcade.Body.setCollideWorldBounds now has a new optional parameter onWorldBounds which allows you to enable the Body's onWorldBounds property in the same call (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityX is a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityY is a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)
  • The PhysicsGroup config now has two new optional properties maxVelocityX and maxVelocityY which allows you to set the maximum velocity on bodies added to the Group (thanks @samme)
  • The Arcade.Body.resetFlags method has a new optional boolean parameter clear. If set, it clears the wasTouching flags on the Body. This happens automatically when Body.reset is called. Previous to this, the flags were not reset until the next physics step (thanks @samme)
  • Physics.Arcade.ProcessX is a new set of functions, called by the SeparateX function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Physics.Arcade.ProcessY is a new set of functions, called by the SeparateY function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Arcade.Body.center values were incorrect after collisions with the world bounds or (for rectangular bodies) after collisions with another body. The body center is now updated after those separations (thanks @samme)
  • The Arcade Physics WORLD_STEP event now has a new parameter: the delta argument (thanks @samme)
  • The Arcade Body drag property has been redefined when damping is used and scales the damping multiplier by the physics step delta. Drag is now the velocity retained after 1 second instead of after 1 step, when damping is used. This makes damping consistent for different physics step rates and more accurate when fixedStep is off. If you use drag you will need to change any existing drag values to get the same effects as before. Convert drag to drag ^ 60 or drag ^ fps if you use a different step rate (thanks @samme)

Loader Cache Changes

When loading any of the file types listed below it will no longer store the data file in the cache. For example, when loading a Texture Atlas using a JSON File, it used to store the parsed image data in the Texture Manager and also store the JSON in the JSON Cache under the same key. This has changed in 3.50. The data files are no longer cached, as they are not required by the textures once parsing is completed, which happens during load. This helps free-up memory. How much depends on the size of your data files. And also allows you to easily remove textures based on just their key, without also having to clear out the corresponding data cache.

  • AtlasJSONFile no longer stores the JSON in the JSON Cache once the texture has been created.
  • AtlasXMLFile no longer stores the XML in the XML Cache once the texture has been created.
  • UnityAtlasFile no longer stores the Text in the Text Cache once the texture has been created.
  • BitmapFontFile no longer stores the XML in the XML Cache once the texture has been created.
  • You can now use TextureManager.remove to remove a texture and not have to worry about clearing the corresponding JSON or XML cache entry as well in order to reload a new texture using the same key. Fix #5323 (thanks @TedGriggs)

ColorMatrix

  • Phaser.Display.ColorMatrix is a new class that allows you to create and manipulate a 5x4 color matrix, which can be used by shaders or graphics operations.
  • The ColorMatrix.set method allows you to set the values of a ColorMatrix.
  • The ColorMatrix.reset method will reset the ColorMatrix to its default values.
  • The ColorMatrix.getData method will return the data in the ColorMatrix as a Float32Array, useful for setting in a shader uniform.
  • The ColorMatrix.brightness method lets you set the brightness of the ColorMatrix.
  • The ColorMatrix.saturate method lets you set the saturation of the ColorMatrix.
  • The ColorMatrix.desaturate method lets you desaturate the colors in the ColorMatrix.
  • The ColorMatrix.hue method lets you rotate the hues of the ColorMatrix by the given amount.
  • The ColorMatrix.grayscale method converts the ColorMatrix to grayscale.
  • The ColorMatrix.blackWhite method converts the ColorMatrix to black and whites.
  • The ColorMatrix.contrast method lets you set the contrast of the ColorMatrix.
  • The ColorMatrix.negative method converts the ColorMatrix to negative values.
  • The ColorMatrix.desaturateLuminance method applies a desaturated luminance to the ColorMatrix.
  • The ColorMatrix.sepia method applies a sepia tone to the ColorMatrix.
  • The ColorMatrix.night method applies a night time effect to the ColorMatrix.
  • The ColorMatrix.lsd method applies a trippy color effect to the ColorMatrix.
  • The ColorMatrix.brown method applies a brown tone to the ColorMatrix.
  • The ColorMatrix.vintagePinhole method applies a vintage pinhole color effect to the ColorMatrix.
  • The ColorMatrix.kodachrome method applies a kodachrome color effect to the ColorMatrix.
  • The ColorMatrix.technicolor method applies a technicolor color effect to the ColorMatrix.
  • The ColorMatrix.polaroid method applies a polaroid color effect to the ColorMatrix.
  • The ColorMatrix.shiftToBGR method shifts the values of the ColorMatrix into BGR order.
  • The ColorMatrix.multiply method multiplies two ColorMatrix data sets together.

Removal of 'resolution' property from across the API

For legacy reasons, Phaser 3 has never properly supported HighDPI devices. It will render happily to them of course, but wouldn't let you set a 'resolution' for the Canvas beyond 1. Earlier versions of 3.x had a resolution property in the Game Config, but it was never fully implemented (for example, it would break zooming cameras). When the Scale Manager was introduced in v3.16 we forced the resolution to be 1 to avoid it breaking anything else internally.

For a long time, the 'resolution' property has been present - taunting developers and confusing new comers. In this release we have finally gone through and removed all references to it. The Game Config option is now gone, it's removed from the Scale Manager, Base Camera and everywhere else where it matters. As much as we would have liked to implement the feature, we've spent too long without it, and things have been built around the assumption it isn't present. The API just wouldn't cope with having it shoe-horned in at this stage. As frustrating as this is, it's even more annoying to just leave the property there confusing people and wasting CPU cycles. Phaser 4 has been built with HighDPI screens in mind from the very start, but it's too late for v3. The following changes are a result of this removal:

  • The Phaser.Scale.Events#RESIZE event no longer sends the resolution as a parameter.
  • The BaseCamera.resolution property has been removed.
  • The internal private BaseCamera._cx, _cy, _cw and _ch properties has been removed, use x, y, width and height instead.
  • The BaseCamera.preRender method no longer receives or uses the resolution parameter.
  • The Camera.preRender method no longer receives or uses the resolution parameter.
  • The CameraManager.onResize method no longer receives or uses the resolution parameter.
  • The Core.Config.resolution property has been removed.
  • The TextStyle.resolution property is no longer read from the Game Config. You can still set it via the Text Style config to a value other than 1, but it will default to this now.
  • The CanvasRenderer no longer reads or uses the Game Config resolution property.
  • The PipelineManager.resize method along with WebGLPipeline.resize and anything else that extends them no longer receives or uses the resolution parameter.
  • The WebGLRenderer.resize and onResize methods no longer receives or uses the resolution parameter.
  • The ScaleManager.resolution property has been removed and all internal use of it.

Removed 'interpolationPercentage' parameter from all render functions

Since v3.0.0 the Game Object render functions have received a parameter called interpolationPercentage that was never used. The renderers do not calculate this value and no Game Objects apply it, so for the sake of clairty, reducing code and removing complexity from the API it has been removed from every single function that either sent or expected the parameter. This touches every single Game Object and changes the parameter order as a result, so please be aware of this if you have your own custom Game Objects, or plugins, that implement their own render methods. In terms of surface API changes, you shouldn't notice anything at all from this removal.

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.
  • You can now use this.renderer from within a Scene, as it's now a Scene-level property and part of the Injection Map.
  • Clock.addEvent can now take an existing TimerEvent object, as well as a config object. If a TimerEvent is given it will be removed from the Clock, reset and then added. This allows you to pool TimerEvents rather than constantly create and delete them. Fix #4115 (thanks @jcyuan)
  • Clock.removeEvent is a new method that allows you to remove a TimerEvent, or an array of them, from all internal lists of the current Clock.
  • Group.getMatching is a new method that will return any members of the Group that match the given criteria, such as getMatching('visible', true) (thanks @atursams)
  • Utils.Array.SortByDigits is a new function that takes the given array of strings and runs a numeric sort on it, ignoring any non-digits.
  • GroupCreateConfig, which is used when calling Group.createMultiple or Group.createFromConfig, can now accept the following new properties: setOrigin: { x, y, stepX, stepY } which are applied to the items created by the Group.
  • Transform.copyPosition is a new method that will copy the position from the given object to the Game Object (thanks @samme)
  • The Text.MeasureText function, which is used to calculate the ascent and descent of Text Game Objects whenever the style, or font size, is changed, has been updated to use the new actualBoundingBoxAscent functions present in modern browsers. This allows for significantly faster ascent calculations than previously. Older browsers, such as IE, will still fall back (thanks @rexrainbow)
  • GameObjects.GetCalcMatrix is a new function that is used to calculate the transformed Game Object matrix, based on the given Game Object, Camera and Parent. This function is now used by the following Game Objects: BitmapText (Static and Dynamic), Graphics, Extern, Mesh, Rope, Shader, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. This dramatically reduces the amount of duplicate code across the API.
  • Utils.Array.Matrix.Translate is a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.
  • Vertor3.addScale is a new method that will add the given vector and multiply it in the process.
  • When defining the ease used with a Particle Emitter you can now set easeParams in the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh)
  • BitmapMask.createMask is a new method that will internally create the WebGL textures and framebuffers required for the mask. This is now used by the constructor and if the context is lost. It now also clears any previous textures/fbos that may have been created first, helping prevent memory leaks.
  • BitmapMask.clearMask will delete any WebGL textures or framebuffers the mask is using. This is now called when the mask is destroyed, or a new mask is created upon it.
  • Quaternion now has a new property onChangeCallback which, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.
  • The Quaternion.set method has a new optional boolean parameter update (defaults to true), which will call the onChangeCallback if set.
  • Quaternion.setFromEuler is a new method that will set the quaternion from the given Euler object, optionally calling the onChangeCallback in the process.
  • Quaternion.setFromRotationMatrix is a new method that will set the rotation of the quaternion from the given Matrix4.
  • Vector3.setFromMatrixPosition is a new method that will set the components of the Vector3 based on the position of the given Matrix4.
  • Vector3.setFromMatrixColumn is a new method that will set the components of the Vector3 based on the specified Matrix4 column.
  • Vector3.fromArray is a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.
  • Vector3.min is a new method that will set the components of the Vector3 based on the Main.min between it and the given Vector3.
  • Vector3.max is a new method that will set the components of the Vector3 based on the Main.max between it and the given Vector3.
  • Vector3.addVectors is a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.
  • Vector3.addScalar is a new method that will multiply the components of the Vector3 by the scale value given.
  • Vector3.applyMatrix3 is a new method that will take a Matrix3 and apply it to the Vector3.
  • Vector3.applyMatrix4 is a new method that will take a Matrix4 and apply it to the Vector3.
  • Vector3.projectViewMatrix is a new method that multiplies the Vector3 by the given view and projection matrices.
  • Vector3.unprojectViewMatrix is a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.
  • Matrix4.setValues is a new method that allows you to set all of the matrix components individually. Most internal methods now use this.
  • Matrix.multiplyToMat4 is a new method that multiplies a Matrix4 by the given src Matrix4 and stores the results in the out Matrix4.
  • Matrix4.fromRotationXYTranslation is a new method that takes the rotation and position vectors and builds this Matrix4 from them.
  • Matrix4.getMaxScaleOnAxis is a new method that will return the maximum axis scale from the Matrix4.
  • Matrix4.lookAtRH is a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.
  • Matrix4.transform is a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.
  • Matrix4.multiplyMatrices is a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.
  • Matrix4.premultiply is a new method that takes a Matrix4 and multiplies it by the current Matrix4.
  • Matrix4.getInverse is a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.
  • CameraManager.getVisibleChildren is a new method that is called internally by the CameraManager.render method. It filters the DisplayList, so that Game Objects that pass the willRender test for the given Camera are added to a sub-list, which is then passed to the renderer. This avoids the renderer having to do any checks on the children, it just renders each one in turn.
  • Physics.Arcade.Body.setDamping is a new method that allows you to set the useDamping property of a Body in a chainable way. Fix #5352 (thanks @juanitogan)
  • The GameObjects.Graphics.fillGradientStyle method can now accept a different alpha value for each of the fill colors. The default is still 1. If you only provide a single alpha, it'll be used for all colors. Fix #5044 (thanks @zhangciwu)
  • Types.Core.PipelineConfig is a new configuration object that you can set in the Game Config under the pipeline property. It allows you to define custom WebGL pipelines as part of the Game Config, so they're automatically installed and ready for use by all Scenes in your game. You can either set the pipeline object, or set it under the render sub-config.
  • Utils.Object.DeepCopy is a new function that will recursively deep copy an array of object.
  • Time.TimerEvent.getRemaining is a new method that returns the time interval until the next iteration of the Timer Event (thanks @samme)
  • Time.TimerEvent.getRemainingSeconds is a new method that returns the time interval until the next iteration of the Timer Event in seconds (thanks @samme)
  • Time.TimerEvent.getOverallRemaining is a new method that returns the time interval until the last iteration of the Timer Event (thanks @samme)
  • Time.TimerEvent.getOverallRemainingSeconds is a new method that returns the time interval until the last iteration of the Timer Event in seconds (thanks @samme)
  • GameObjects.Video.loadMediaStream is a new method that allows you to hook a Video Game Object up to a Media Stream, rather than a URL, allowing you to stream video from a source such as a webcam (thanks @pirateksh)
  • Display.Color.ColorSpectrum is a new function that will return an array of 1024 Color Object elements aligned in a Color Spectrum layout, where the darkest colors have been omitted.
  • AsepriteFile is a new File Type for the Loader that allows you to load Aseprite images and animation data for use with the new Aseprite animation features. You can call this via this.load.asesprite(png, json).
  • GameObject.displayList is a new property that contains a reference to the Display List to which the Game Object has been added. This will typically either by the Display List owned by a Scene, or a Layer Game Object. You should treat this property as read-only.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Earcut has now been exposed and is available via Geom.Polygon.Earcut and is fully documented.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.
  • Pointer.downTime now stores the event timestamp of when the first button on the input device was pressed down, not just when button 1 was pressed down.
  • Pointer.upTime now stores the event timestamp of when the final depressed button on the input device was released, not just when button 1 was released.
  • The Pointer.getDuration method now uses the new Pointer downTime and upTime values, meaning it will accurately report the duration of when any button is being held down, not just the primary one. Fix #5112 (thanks @veleek)
  • The BaseShader default vertex shader now includes the outTexCoord vec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok)
  • When using the GameObjectCreator for Containers you can now specify the children property in the configuration object.
  • Textures.Parsers.JSONHash will now perform a hasOwnProperty check when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes from JSON.parse. Fix #4768 (thanks @RollinSafary)
  • The Camera3D Plugin has been rebuilt for Phaser 3.50 and the webpack config updated. This plugin is now considered deprecated and will not be updated beyond this release.
  • Tween.seek will no longer issue a console warning for 'Tween.seek duration too long', it's now up to you to check on the performance of tween seeking.
  • If inputWindowEvents is set in the Game Config, then the MouseManager will now listen for the events on window.top instead of just window, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in a try/catch block, as not all sites allow access to window.top (specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow)
  • MouseManager.isTop is a new boolean read-only property that flags if the mouse event listeners were attached to window.top (true), or just window (false). By default Phaser will attempt window.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back to window in those cases and set this property to false (thanks BunBunBun)
  • Types.GameObjects.Text.GetTextSizeObject is a new type def for the GetTextSize function results.
  • Utils.Array.StableSort has been recoded. It's now based on Two-Screens stable sort 0.1.8 and has been updated to fit into Phaser better and no longer create any window bound objects. The inplace function has been removed, just call StableSort(array) directly now. All classes that used StableSort.inplace have been updated to call it directly.
  • If a Scene is paused, or sent to sleep, it will automatically call Keyboard.resetKeys. This means that if you hold a key down, then sleep or pause a Scene, then release the key and resume or wake the Scene, it will no longer think it is still being held down (thanks @samme)
  • Actions.setOrigin will now call updateDisplayOrigin on the items array, otherwise the effects can't be seen when rendering.
  • You can now set the ArcadeWorld.fixedStep property via the ArcadeWorldConfig object (thanks @samme)
  • Utils.Array.NumerArray can now accept the start and end parameters in reverse order, i.e. 10, 1 will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.
  • DataManager.Events.DESTROY is a new event that the Data Manager will listen for from its parent and then call its own destroy method when received.
  • The Quaternion class constructor will now default the values to 0,0,0,1 if they're not provided, making it an identity quaternion, rather than the 0,0,0,0 it was before.
  • You can now set the ParticleEmitter.reserve value via the emitter configuration object (thanks @vforsh)
  • Setting the pixelArt config option will now set antialiasGL to false, as well as antialias. Fix #5309 (thanks @Vegita2)
  • The Shape class now includes the ComputedSize component properties and methods directly in the class, rather than applying as a mixin. setSize is now flagged as being private, because it shouldn't be used on Shape classes, which was leading to confusion as it appeared in the public-facing API. Fix #4811 (thanks @aolsx)
  • The Loader.maxParallelDownloads value is now set to 6 if running on Android, or 32 on any other OS. This avoids net::ERR_FAILED issues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary)
  • When running an Arcade Physics overlap test against a StaticBody, it will no longer set the blocked states of the dynamic body. If you are doing a collision test, they will still be set, but they're skipped for overlap-only tests. Fix #4435 (thanks @samme)
  • The Line Game Object will now default its width and height to 1, rather than zero. This allows you to give Line objects a physics body (although you will still need to re-adjust the center of the body manually). Fix #4596 (thanks @andrewaustin)
  • Internally, the Quaternion class now has 4 new private properties: _x, _y, _z and _w and 4 new getters and setters for the public versions. It also now passes most methods via set to allow for the onChange callback to be invoked. This does not change the public-facing API.
  • Group now extends EventEmitter, allowing you to emit custom events from within a Group.
  • Device.Audio.wav now uses audio/wav as the canPlayType check string, instead of audio/wav; codecs="1", which should allow iOS13 to play wav files again.
  • In the Loader.FileTypes.TextFile config you can now override the type and cache destination for the file.
  • Loader.MultiFile will now parse the given files array and only add valid entries into the file list, allowing multifiles to now have optional file entries.
  • The ParticleEmitter.tint value is now 0xffffff (previously, it was 0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh)
  • SceneManager.start will now reset the SceneSystems.sceneUpdate reference to NOOP. This gets set back to the Scene update method again during bootScene (if it has one) and stops errors with external plugins and multi-part files that may trigger update before create has been called. Fix #4629 (thanks @Osmose)
  • Phaser.Scene.renderer is a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.
  • The CanvasRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.
  • Since iOS 13, iPads now identify as MacOS devices. A new maxTouchPoint check is now part of the Device.OS tests, stopping iPads from being flagged as desktop devices. Fix #5389 (thanks @SBCGames)
  • The BitmapMask.prevFramebuffer property has been removed as it's no longer required, due to the fbo stack in the renderer.
  • The TextureManager.addGLTexture method has been updated so that the width and height parameters are now optional. If not provided, and if available, they will be read from the given WebGLTexture instead (thanks @hexus)
  • GameObjects.Components.Depth.depthList is a new property that all Game Objects that have the Depth Component now have. It contains a reference to the List responsible for managing the depth sorting of the Game Object. This is typically the Scene Display List, but can also be a Layer. It allows the Depth component to queue a depth sort directly on the list it belongs to now, rather than just the Scene.

Bug Fixes

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)
  • The GridAlign action didn't work if only the height parameter was set. Fix #5019 (thanks @halilcakar)
  • The Color.HSVToRGB function has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX)
  • Previously, the easeParams array within a Tweens props object, or a multi-object tween, were ignored and it was only used if set on the root Tween object. It will now work correctly set at any depth. Fix #4292 (thanks @willblackmore)
  • When using Camera.setRenderToTexture its zoom and rotation values would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok)
  • GameObjects.Shape.Grid would render a white fill even if you passed undefined as the fill color in the constructor. It now doesn't render cells if no fill color is given.
  • The onMouse events in the Input Manager didn't reset the activePointer property to the mouse, meaning on dual-input systems such as Touch Screen devices, the active pointer would become locked to whichever input method was used first. Fix #4615 #5232 (thanks @mmolina01 @JstnPwll @Legomite)
  • The Scale Managers GetScreenOrientation function will now check for window.orientation first, because iOS mobile browsers have an incomplete implementation of the Screen API, forcing us to use the window value as a priority. This means the Scale Manager will now emit orientationchange events correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu)
  • Time.Clock.addEvent can now take an instance of a TimerEvent as its parameter. Fix #5294 (thanks @samme @EmilSV)
  • GameConfig.audio now defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)
  • The Loader.path was being added to the File URL even if the URL was absolute. This is now checked for and the path is not applied unless the URL is relative (thanks @firesoft)
  • Group.getMatching would always return an empty array. It now returns matching children (thanks @samme)
  • The ParticleManagerWebGLRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in follow offsets separately. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers. Fix #5319 #5195 #4739 #4691 (thanks @vforsh @condeagustin @IvanDem @Formic)
  • The ParticleManagerCanvasRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also uses setToContext internally. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers, or having the Camera zoomed, running under Canvas. Fix #4908 #4531 #4131 (thanks @smjnab @SirLink @jhooper04)
  • The Graphics WebGL Renderer will now default to pathOpen = true. This fixes issues under WebGL where, for example, adding an arc and calling strokePath, without first calling beginPath will no longer cause rendering artefacts when WebGL tries to close the path with a single tri.
  • Graphics.strokeRoundedRect now issues moveTo commands as part of the drawing sequence, preventing issues under WebGL where on older Android devices it would project additional vertices into the display. Fix #3955 (thanks @alexeymolchan)
  • Creating a Bitmap Mask from a texture atlas that was then used to mask another Game Object also using that same texture atlas would throw the error GL_INVALID_OPERATION : glDrawArrays: Source and destination textures of the draw are the same.. It now renders as expected. Fix #4675 (thanks @JacobCaron)
  • When using the same asset for a Game Object to be used as a mask, it would make other Game Objects using the same asset, that appeared above the mask in the display list, to not render. Fix #4767 (thanks @smjnab)
  • When taking a snapshot in WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in the WebGLSnapshot function. Fix #4956 (thanks @gammafp @telinc1)
  • You can now draw a Group to a RenderTexture. Previously, it failed to pass the camera across, resulting in none of the Group children being drawn. Fix #5330 (thanks @somnolik)
  • Particles.EmitterOp.setMethods will now reset both onEmit and onUpdate to their default values. This allows you to reconfigure an emitter op with a new type of value and not have it stuck on the previous one. Fix #3663 (thanks @samme)
  • Particles.EmitterOp now cleanly separates between the different types of property configuration options. start | end will now ease between the two values, min | max will pick a random value between them and random: [] will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)
  • When setting both transparent: true and backgroundColor in the Game Config, it would ignore the transparency and use the color anyway. If transparent, the game is now fully transparent. Fix #5362 (thanks @Hoshinokoe)
  • The Ellipse Game Object now will update the width, height, and geometric position in the setSize method (thanks @PhaserEditor2D)
  • When measuring the last word in a line in a Text Game Object, it no longer adds extra white space to the end (thanks @rexrainbow)
  • Utils.Array.Remove would return an incorrect array of removed elements if one of the items to be removed was skipped in the array. Fix #5398 (thanks @year221)
  • Geom.Intersects.TriangleToLine wouldn't return true if the start or end of the Line fell inside the Triangle, only if the entire Line did. It now checks the start and end points correctly. (thanks @wiserim)
  • Using a Bitmap Mask and a Blend Mode in WebGL would reset the blend mode when the mask was rendered, causing the Game Object to have no blend mode. Fix #5409 (thanks @jcyuan)

Namespace Updates

  • The Phaser.Curves.MoveTo function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.DOM.GetInnerHeight function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Bob class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsManager class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsPlugin class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Particles.EmitterOp class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.GetTextSize function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.MeasureText function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.TextStyle function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Input.CreatePixelPerfectHandler function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapCirc function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapRect function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Tilemap namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Components namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.MatterGameObject class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.PointerConstraint class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetPhysicsPlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetScenePlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Structs.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Tilemaps.Parsers.Tiled function has now been exposed on the Phaser namespace (thanks @samme)
  • Every single Tilemap.Component function has now been made public. This means you can call the Component functions directly, should you need to, outside of the Tilemap system.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360 @volkans80 @jaabberwocky @maikthomas @atursams @LearningCode2023 @DylanC @BenjaminDRichards @rexrainbow @Riderrr @spwilson2 @EmilSV @PhaserEditor2D @Gangryong @vinerz @trynx @usufruct99 @pirateksh @justin-calleja @monteiz

- JavaScript
Published by photonstorm over 5 years ago

phaser - Phaser v3.50.0 Beta 10

Version 3.50.0 - Subaru - in development

WebGL Pipeline Updates

If you use a custom WebGL Pipeline in your game, you must update your code in order to use Phaser 3.50.

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

There is also the new GraphicsPipeline. Previously, the TextureTintPipeline was responsible for rendering all Sprites, Graphics and Shape objects. Now, it only renders Sprites. All Graphics and Shapes are handled by the new GraphicsPipeline which uses its own shaders. See further below for details about this change.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

Other pipeline changes are as follows:

  • None of the shaders or pipelines use the uViewMatrix and uModelMatrix uniforms any longer. These were always just plain identity matrices, so there is no point spending CPU and GPU time to set them as uniforms, or use them in the shaders. Should you need these uniforms, you can add them to your own custom pipelines.
  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.
  • The WebGLPipeline.shouldFlush method now accepts an optional parameter amount. If given, it will return true if when the amount is added to the vertex count it will exceed the vertex capacity. The Multi Pipeline has been updated to now use this method instead of performing the comparison multiple times itself.
  • The RopePipeline now extends MultiPipeline and just changes the topolgy, vastly reducing the filesize.
  • The WebGLPipeline.flushLocked property has been removed. A pipeline can never flush in the middle of a flush anyway, so it was just wasting CPU cycles being set.
  • You can now pass a pipeline instance to the GameObject.setPipeline method, as well as a string.

Pipeline Uniform Changes

Piplines now have a new uniforms array that can be passed in with the config. All default pipelines now set these. The array contains the names, as strings, of all uniforms your pipeline shader uses. Once the pipeline shader has been successfully linked, it will use the array of names to look-up the WebGLUniformLocation of all uniforms specified. These are stored in the new WebGLPipeline.uniforms object. This takes place in the new WebGLPipeline.setUniformLocations method.

When a pipeline is bound, you can now use the new methods (listed below) to set uniform values directly on the pipeline. Previously, calling a method such as setFloat3 on a pipeline would pass that call over to WebGLRenderer. The renderer would first check to see if the pipeline program was current, and if not, make it so, before then looking up the uniform location and finally setting it. This is a lot of steps to take for pipelines that potentially need to change uniforms for every Game Object they render.

Under the new methods, and using the new pre-cached uniform locations, these extra steps are skipped. The uniform value is set directly, no shader binding takes place and no location look-up happens. This dramatically reduces the number of WebGL ops being issued per frame. To clearly differentiate these pipline methods, we have renamed them. The new method names are as follows:

  • WebGLPipeline.set1f will set a 1f uniform based on the given name.
  • WebGLPipeline.set2f will set a 2f uniform based on the given name.
  • WebGLPipeline.set3f will set a 3f uniform based on the given name.
  • WebGLPipeline.set4f will set a 4f uniform based on the given name.
  • WebGLPipeline.set1fv will set a 1fv uniform based on the given name.
  • WebGLPipeline.set2fv will set a 2fv uniform based on the given name.
  • WebGLPipeline.set3fv will set a 3fv uniform based on the given name.
  • WebGLPipeline.set4fv will set a 4fv uniform based on the given name.
  • WebGLPipeline.set1iv will set a 1iv uniform based on the given name.
  • WebGLPipeline.set2iv will set a 2iv uniform based on the given name.
  • WebGLPipeline.set3iv will set a 3iv uniform based on the given name.
  • WebGLPipeline.set4iv will set a 4iv uniform based on the given name.
  • WebGLPipeline.set1i will set a 1i uniform based on the given name.
  • WebGLPipeline.set2i will set a 2i uniform based on the given name.
  • WebGLPipeline.set3i will set a 3i uniform based on the given name.
  • WebGLPipeline.set4i will set a 4i uniform based on the given name.
  • WebGLPipeline.setMatrix2fv will set a matrix 2fv uniform based on the given name.
  • WebGLPipeline.setMatrix3fv will set a matrix 3fv uniform based on the given name.
  • WebGLPipeline.setMatrix4fv will set a matrix 4fv uniform based on the given name.

If your code uses any of the old method names, please update them using the list below:

  • WebGLPipeline.setFloat1 has been removed. Please use set1f instead.
  • WebGLPipeline.setFloat2 has been removed. Please use set2f instead.
  • WebGLPipeline.setFloat3 has been removed. Please use set3f instead.
  • WebGLPipeline.setFloat4 has been removed. Please use set4f instead.
  • WebGLPipeline.setFloat1v has been removed. Please use set1fv instead.
  • WebGLPipeline.setFloat2v has been removed. Please use set2fv instead.
  • WebGLPipeline.setFloat3v has been removed. Please use set3fv instead.
  • WebGLPipeline.setFloat4v has been removed. Please use set4fv instead.
  • WebGLPipeline.setInt1 has been removed. Please use set1i instead.
  • WebGLPipeline.setInt2 has been removed. Please use set2i instead.
  • WebGLPipeline.setInt3 has been removed. Please use set3i instead.
  • WebGLPipeline.setInt4 has been removed. Please use set4i instead.
  • WebGLPipeline.setMatrix1 has been removed. Please use setMatrix2fv instead.
  • WebGLPipeline.setMatrix2 has been removed. Please use setMatrix3fv instead.
  • WebGLPipeline.setMatrix3 has been removed. Please use setMatrix4fv instead.

Pipeline Manager

The WebGL.PipelineManager is a new class that is responsbile for managing all of the WebGL Pipelines in Phaser. An instance of the Pipeline Manager is created by the WebGL Renderer and is available under the pipelines property. This means that the WebGL Renderer no longer handles pipelines directly, causing the following API changes:

  • WebGLRenderer.pipelines is no longer a plain object containing pipeline instances. It's now an instance of the PipelineManager class. This instance is created during the init and boot phase of the renderer.
  • The WebGLRenderer.currentPipeline property no longer exists, instead use PipelineManager.current.
  • The WebGLRenderer.previousPipeline property no longer exists, instead use PipelineManager.previous.
  • The WebGLRenderer.hasPipeline method no longer exists, instead use PipelineManager.has.
  • The WebGLRenderer.getPipeline method no longer exists, instead use PipelineManager.get.
  • The WebGLRenderer.removePipeline method no longer exists, instead use PipelineManager.remove.
  • The WebGLRenderer.addPipeline method no longer exists, instead use PipelineManager.add.
  • The WebGLRenderer.setPipeline method no longer exists, instead use PipelineManager.set.
  • The WebGLRenderer.rebindPipeline method no longer exists, instead use PipelineManager.rebind.
  • The WebGLRenderer.clearPipeline method no longer exists, instead use PipelineManager.clear.

The Pipeline Manager also offers the following new features:

  • The PipelineManager.resize method automatically handles resize events across all pipelines.
  • The PipelineManager.preRender method calls the pre-render method of all pipelines.
  • The PipelineManager.render method calls the render method of all pipelines.
  • The PipelineManager.postRender method calls the post-render method of all pipelines.
  • The PipelineManager.setMulti method automatically binds the Multi Texture Pipeline, Phaser's default.
  • The PipelineManager.clear method will clear the pipeline, store it in previous and free the renderer.
  • The PipelineManager.rebind method will reset the rendering context and restore the previous pipeline, if set.

New constants have been created to help you reference a pipeline without needing to use strings:

  • Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE for the Bitmap Mask Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE for the Light 2D Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE for the Single Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE for the Multi Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE for the Rope Pipeline.

All Game Objects have been updated to use the new constants and Pipeline Manager.

Single Pipeline

There is also a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGL Multi-Texture Rendering

The Multi Pipeline (previously called the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw-call bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLPipeline.forceZero is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.
  • The WebGL.Utils.getComponentCount function has been removed as this is no longer required internally.

WebGLRenderer New Features, Updates and API Changes

  • WebGLRenderer.instancedArraysExtension is a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.
  • WebGLRenderer.vaoExtension is a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.
  • WebGLRenderer.resetProgram is a new method that will rebind the current program, without flushing or changing any properties.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • WebGLRenderer.finalType is a new boolean property that signifies if the current Game Object being rendered is the final one in the list.
  • The WebGLRenderer.updateCanvasTexture method will now set gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL to true, which should stop issues where you update a Text Game Object, having added a Render Texture or Spine Game Object to the Scene after it, which switches the PMA setting. Fix #5064 #5155 (thanks @hugoruscitti @immangrove-supertree)
  • WebGLRenderer.previousPipeline is a new property that is set during a call to clearPipeline and used during calls to rebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.
  • The WebGLRenderer.rebindPipeline method has been changed slightly. Previously, you had to specify the pipelineInstance, but this is now optional. If you don't, it will use the new previousPipeline property instead. If not set, or none given, it will now return without throwing gl errors as well.
  • WebGLRenderer.defaultScissor is a new property that holds the default scissor dimensions for the renderer. This is modified during resize and avoids continuous array generation in the preRender loop.
  • The WebGLRenderer.nativeTextures array has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in the TextureSource objects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy.
  • The WebGLRenderer.deleteTexture method has a new optional boolean parameter reset which allows you to control if the WebGLRenderer.resetTextures method is called, or not, after the texture is deleted.
  • The WebGLRenderer.getMaxTextures method has been removed. This is no longer needed as you can use the WebGLRenderer.maxTextures property instead.
  • The WebGLRenderer.setProgram method now returns a boolean. true if the program was set, otherwise false.
  • The WebGLRenderer.setVertexBuffer method now returns a boolean. true if the buffer was set, otherwise false.
  • WebGLRenderer.setFloat1 has been removed. Use WebGLPipeline.set1f or WebGLShader.set1f instead.
  • WebGLRenderer.setFloat2 has been removed. Use WebGLPipeline.set2f or WebGLShader.set2f instead.
  • WebGLRenderer.setFloat3 has been removed. Use WebGLPipeline.set3f or WebGLShader.set3f instead.
  • WebGLRenderer.setFloat4 has been removed. Use WebGLPipeline.set4f or WebGLShader.set4f instead.
  • WebGLRenderer.setFloat1v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set1fv instead.
  • WebGLRenderer.setFloat2v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set2fv instead.
  • WebGLRenderer.setFloat3v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set3fv instead.
  • WebGLRenderer.setFloat4v has been removed. Use WebGLPipeline.set1fv or WebGLShader.set4fv instead.
  • WebGLRenderer.setInt1 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set1i instead.
  • WebGLRenderer.setInt2 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set2i instead.
  • WebGLRenderer.setInt3 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set3i instead.
  • WebGLRenderer.setInt4 has been removed. Use WebGLPipeline.set1fi or WebGLShader.set4i instead.
  • WebGLRenderer.setMatrix2 has been removed. Use WebGLPipeline.setMatrix2fv or WebGLShader.setMatrix2fv instead.
  • WebGLRenderer.setMatrix3 has been removed. Use WebGLPipeline.setMatrix3fv or WebGLShader.setMatrix3fv instead.
  • WebGLRenderer.setMatrix4 has been removed. Use WebGLPipeline.setMatrix4fv or WebGLShader.setMatrix4fv instead.
  • The WebGLRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.
  • WebGLRenderer.fboStack is a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.
  • WebGLRenderer.pushFramebuffer is a new method that is used to push a framebuffer onto the fbo stack before setting it as the current framebuffer. This should now be called in place of setFramebuffer. Remember to call popFramebuffer after using it.
  • WebGLRenderer.popFramebuffer is a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.
  • WebGLRenderer.setFramebuffer has a new optional boolean parameter resetTextures which will reset the WebGL Textures, if set to true (which is the default).

Camera - New Features, Updates and API Changes

The Camera API has changed in line with the new pipeline updates. To this end, the following changes have taken place:

The Camera class now inherits the Pipeline Component. This gives it new features, in line with the other pipelines changes in 3.50, such as Camera.setPipeline, Camera.setPostPipeline, Camera.setPipelineData and so on. This is a much more powerful and flexible way of setting camera effects, rather than it managing its own framebuffer and texture directly.

To that end, the following properties and methods have been removed to tidy things up:

  • The Camera.renderToTexture property has been removed. Effects are now handled via pipelines.
  • The Camera.renderToGame property has been removed. Effects are now handled via pipelines.
  • The Camera.canvas property has been removed. Textures are handled by pipelines.
  • The Camera.context property has been removed. Textures are handled by pipelines.
  • The Camera.glTexture property has been removed. GL Textures are handled by pipelines.
  • The Camera.framebuffer property has been removed. GL Framebuffers are handled by pipelines.
  • The Camera.setRenderToTexture method has been removed. Effects are now handled via pipelines.
  • The Camera.clearRenderToTexture method has been removed. Effects are now handled via pipelines.

These changes mean that you can no longer render a Camera to a canvas in Canvas games.

Other changes and fixes:

  • Cameras.Scene2D.Events.FOLLOW_UPDATE is a new Event that is dispatched by a Camera when it is following a Game Object. It is dispatched every frame, right after the final Camera position and internal matrices have been updated. Use it if you need to react to a camera, using its most current position and the camera is following something. Fix #5253 (thanks @rexrainbow)
  • If the Camera has roundPixels set it will now round the internal scroll factors and worldView during the preRender step. Fix #4464 (thanks @Antriel)

Graphics Pipeline and Graphics Game Object Changes

The Graphics Pipeline is a new pipeline added in 3.50 that is responsible for rendering Graphics Game Objects and all of the Shape Game Objects, such as Arc, Rectangle, Star, etc. Due to the new pipeline some changes have been made:

  • The Graphics Pipeline now uses much simpler vertex and fragment shaders, with just two attributes (inPosition and inColor), making the vertex size and memory-use 57% smaller.
  • The private _tempMatrix1, 2, 3 and 4 properties have all been removed from the pipeline.
  • A new public calcMatrix property has been added, which Shape Game Objects use to maintain transform state during rendering.
  • The Graphics Pipeline no longer makes use of tintEffect or any textures.
  • Because Graphics and Shapes now render with their own pipeline, you are able to exclude the pipeline and those Game Objects entirely from custom builds, further reducing the final bundle size.

As a result of these changes the follow features are no longer available:

  • Graphics.setTexture has been removed. You can no longer use a texture as a 'fill' for a Graphic. It never worked with any shape other than a Rectangle, anyway, due to UV mapping issues, so is much better handled via the new Mesh Game Object.
  • Graphics._tempMatrix1, 2 and 3 have been removed. They're not required internally any longer.
  • Graphics.renderWebGL now uses the standard GetCalcMatrix function, cutting down on duplicate code significantly.

Light Pipeline Changes

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh and Quad Game Objects now support rendering with normal maps.
  • The Graphics Game Objects now support rendering in Light2d. You can even use normal map textures for the texture fills.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • All Shape Game Objects (Rectangle, IsoBox, Star, Polygon, etc) now support rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Both Static and Dynamic Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Lights

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

WebGL ModelViewProjection Removed

The ModelViewProjection object contained a lot of functions that Phaser never used internally. Instead, the functions available in them were already available in the Math.Matrix4 class. So the pipelines have been updated to use a Matrix4 instead and all of the MVP functions have been removed. The full list of removed functions is below:

  • projIdentity has been removed.
  • projPersp has been removed.
  • modelRotateX has been removed.
  • modelRotateY has been removed.
  • modelRotateZ has been removed.
  • viewLoad has been removed.
  • viewRotateX has been removed.
  • viewRotateY has been removed.
  • viewRotateZ has been removed.
  • viewScale has been removed.
  • viewTranslate has been removed.
  • modelIdentity has been removed.
  • modelScale has been removed.
  • modelTranslate has been removed.
  • viewIdentity has been removed.
  • viewLoad2D has been removed.
  • projOrtho has been removed.

BitmapText - New Features, Updates and API Changes

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has to work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.
  • You can now use setMaxWidth on DynamicBitmapText, which wasn't previously possible. Fix #4997 (thanks @AndreaBoeAbrahamsen)

Update List Changes

The way in which Game Objects add themselves to the Scene Update List has changed. Instead of being added by the Factory methods, they will now add and remove themselves based on the new ADDED_TO_SCENE and REMOVED_FROM_SCENE events. This means, you can now add Sprites directly to a Container, or Group, and they'll animate properly without first having to be part of the Update List. The full set of changes and new features relating to this follow:

  • GameObjects.Events.ADDED_TO_SCENE is a new event, emitted by a Game Object, when it is added to a Scene, or a Container that is part of the Scene.
  • GameObjects.Events.REMOVED_FROM_SCENE is a new event, emitted by a Game Object, when it is removed from a Scene, or a Container that is part of the Scene.
  • Scenes.Events.ADDED_TO_SCENE is a new event, emitted by a Scene, when a new Game Object is added to the display list in the Scene, or a Container that is on the display list.
  • Scenes.Events.REMOVED_FROM_SCENE is a new event, emitted by a Scene, when it a Game Object is removed from the display list in the Scene, or a Container that is on the display list.
  • GameObject.addedToScene is a new method that custom Game Objects can use to perform additional set-up when a Game Object is added to a Scene. For example, Sprite uses this to add itself to the Update List.
  • GameObject.removedFromScene is a new method that custom Game Objects can use to perform additional tear-down when a Game Object is removed from a Scene. For example, Sprite uses this to remove themselves from the Update List.
  • Game Objects no longer automatically remove themselves from the Update List during preDestroy. This should be handled directly in the removedFromScene method now.
  • The Container will now test to see if any Game Object added to it is already on the display list, or not, and emit its ADDED and REMOVED events accordingly. Fix #5267 #3876 (thanks @halgorithm @mbpictures)
  • DisplayList.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • DisplayList.addChildCallback is a new method that overrides the List callback and fires the new ADDED events.
  • DisplayList.removeChildCallback is a new method that overrides the List callback and fires the new REMOVED events.
  • GameObjectCreator.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • GameObjectFactory.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • ProcessQueue.checkQueue is a new boolean property that will make sure only unique objects are added to the Process Queue.
  • The Update List now uses the new checkQueue property to ensure no duplicate objects are on the active list.
  • DOMElementFactory, ExternFactory, ParticleManagerFactor, RopeFactory and SpriteFactory all no longer add the objects to the Update List, this is now handled by the ADDED events instead.
  • Sprite, Rope, ParticleEmitterManager, Extern and DOMElement now all override the addedToScene and removedFromScene callbacks to handle further set-up tasks.

Spine Plugin Updates

  • The Spine Runtimes have been updated to 3.8.99, which are the most recent non-beta versions. Please note, you will need to re-export your animations if you're working in a version of Spine lower than 3.8.20.
  • SpineContainer is a new Game Object available via this.add.spineContainer to which you can add Spine Game Objects only. It uses a special rendering function to retain batching, even across multiple container or Spine Game Object instances, resulting in dramatically improved performance compared to using regular Containers. You can still use regular Containers if you need, but they do not benefit from the new batching.
  • A Spine Game Object with setVisible(false) will no longer still cause internal gl commands and is now properly skipped, retaining any current batch in the process. Fix #5174 (thanks @Kitsee)
  • The Spine Game Object WebGL Renderer will no longer clear the type if invisible and will only end the batch if the next type doesn't match.
  • The Spine Game Object WebGL Renderer will no longer rebind the pipeline if it was the final object on the display list, saving lots of gl commands.
  • The Webpack build scripts have all been updated for Webpack 4.44.x. Fix #5243 (thanks @RollinSafary)
  • There is a new npm script npm run plugin.spine.runtimes which will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo into plugins/spine/ in order for this to work and then run npm i.
  • Spine Game Objects can now be rendered to Render Textures. Fix #5184 (thanks @Kitsee)
  • Using > 128 Spine objects in a Container would cause a WebGL: INVALID_OPERATION: vertexAttribPointer: no ARRAY_BUFFER is bound and offset is non-zero error if you added any subsequent Spine objects to the Scene. There is now no limit. Fix #5246 (thanks @d7561985)
  • The Spine Plugin will now work in HEADLESS mode without crashing. Fix #4988 (thanks @raimon-segura)
  • Spine Game Objects now use -1 as their default blend mode, which means 'skip setting it', as blend modes should be handled by the Spine skeletons directly.
  • The Spine TypeScript defs have been updated for the latest version of the plugin and to add SpineContainers.
  • The SpineGameObject.setAnimation method will now use the trackIndex parameter if ignoreIfPlaying is set and run the check against this track index. Fix #4842 (thanks @vinerz)
  • The SpineFile will no longer throw a warning if adding a texture into the Texture Manager that already exists. This allows you to have multiple Spine JSON use the same texture file, however, it also means you now get no warning if you accidentally load a texture that exists, so be careful with your keys! Fix #4947 (thanks @Nomy1)
  • The Spine Plugin destroy method will now no longer remove the Game Objects from the Game Object Factory, or dispose of the Scene Renderer. This means when a Scene is destroyed, it will keep the Game Objects in the factory for other Scenes to use. Fix #5279 (thanks @Racoonacoon)
  • SpinePlugin.gameDestroy is a new method that is called if the Game instance emits a destroy event. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.
  • SpineFile will now check to see if another identical atlas in the load queue is already loading the texture it needs and will no longer get locked waiting for a file that will never complete. This allows multiple skeleton JSONs to use the same atlas data. Fix #5331 (thanks @Racoonacoon)
  • SpineFile now uses a ! character to split the keys, instead of an underscore, preventing the plugin from incorrectly working out the keys for filenames with underscores in them. Fix #5336 (thanks @Racoonacoon)
  • SpineGameObject.willRender is no longer hard-coded to return true. It instead now takes a Camera parameter and performs all of the checks needed before returning. Previously, this happened during the render functions.
  • The Spine Plugin now uses a single instance of the Scene Renderer when running under WebGL. All instances of the plugin (installed per Scene) share the same base Scene Renderer, avoiding duplicate allocations and resizing events under multi-Scene games. Fix #5286 (thanks @spayton BunBunBun)

Animation API - New Features and Updates

If you use Animations in your game, please read the following important API changes in 3.50:

The Animation API has had a significant overhaul to improve playback handling. Instead of just playing an animation based on its global key, you can now supply a new PlayAnimationConfig object instead, which allows you to override any of the default animation settings, such as duration, delay and yoyo (see below for the full list). This means you no longer have to create lots of duplicate animations just to change properties such as duration, and can now set them dynamically at run-time as well.

  • The Animation class no longer extends EventEmitter, as it no longer emits any events directly. This means you cannot now listen for events directly from an Animation instance. All of the events are now dispatched by the Game Objects instead.
  • All of the SPRITE_ANIMATION_KEY events have been removed. Instead, please use the new events which all carry the frameKey parameter, which can be used to handle frame specific events. The only exception to this is ANIMATION_COMPLETE_KEY, which is a key specific version of the completion event.
  • ANIMATION_UPDATE_EVENT is a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.
  • ANIMATION_STOP_EVENT is a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of the stop methods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)
  • The Game Object Component.Animation component has been renamed to AnimationState and has moved namespace. It's now in Phaser.Animations instead of GameObjects.Components to help differentiate it from the Animation class when browsing the documentation.
  • The play, playReverse, playAfterDelay, playAfterRepeat and chain Sprite and Animation Component methods can now all take a Phaser.Types.Animations.PlayAnimationConfig configuration object, as well as a string, as the key parameter. This allows you to override any default animation setting with those defined in the config, giving you far greater control over animations on a Game Object level, without needing to globally duplicate them.
  • AnimationState.create is a new method that allows you to create animations directly on a Sprite. These are not global and never enter the Animation Manager, instead risiding within the Sprite itself. This allows you to use the same keys across both local and global animations and set-up Sprite specific local animations.
  • AnimationState.generateFrameNumbers is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • AnimationState.generateFrameNames is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • All playback methods: play, playReverse, playAfterDelay and playAfterRepeat will now check to see if the given animation key exists locally on the Sprite first. If it does, it's used, otherwise it then checks the global Animation Manager for the key instead.
  • AnimationState.skipMissedFrames is now used when playing an animation, allowing you to create animations that run at frame rates far exceeding the refresh rate, or that will update to the correct frame should the game lag. Feature #4232 (thanks @colorcube)
  • AnimationManager.addMix is a new method that allows you to create mixes 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.
  • AnimationManager.getMix is a new method that will return the mix duration between the two given animations.
  • AnimationManager.removeMix is a new method that will remove the mixture between either two animations, or all mixtures for the given animation.
  • AnimationState.remove is a new method that will remove a locally stored Animation instance from a Sprite.
  • AnimationState.get is a new method that will return a locally stored Animation instance from the Sprite.
  • AnimationState.exists is a new method that will check if a locally stored Animation exists on the Sprite.
  • The internal AnimationState.remove method has been renamed to globalRemove.
  • AnimationState.textureManager is a new property that references the global Texture Manager.
  • AnimationState.anims is a new property that contains locally created Animations in a Custom Map.
  • AnimationState.play and Sprite.play no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • AnimationState.playReverse and Sprite.playReverse no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • The AnimationState.delayedPlay method has been renamed to playAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration.
  • The AnimationState.stopOnRepeat method has been renamed to stopAfterRepeat
  • The AnimationState.getCurrentKey method has been renamed to getName.
  • AnimationState.getFrameName is a new method that will return the key of the current Animation Frame, if an animation has been loaded.
  • AnimationState.playAfterDelay and Sprite.playAfterDelay are new methods that will play the given animation after the delay in ms expires.
  • AnimationState.playAfterRepeat and Sprite.playAfterRepeat are new methods that will play the given animation after the current animation finishes repeating. You can also specify the number of repeats allowed left to run.
  • The AnimationState.chain method is now available on the Sprite class.
  • The AnimationState.stopAfterDelay method is now available on the Sprite class.
  • The AnimationState.stopAfterRepeat method is now available on the Sprite class.
  • The AnimationState.stopOnFrame method is now available on the Sprite class.
  • AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser. Please see the comprehensive documentation for this method for full details on how to do this.
  • AnimationState now handles all of the loading of the animation. It no longer has to make calls out to the Animation Manager or Animation instance itself and will load the animation data directly, replacing as required from the optional PlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.
  • The PlayAnimationConfig.frameRate property lets you optionally override the animation frame rate.
  • The PlayAnimationConfig.duration property lets you optionally override the animation duration.
  • The PlayAnimationConfig.delay property lets you optionally override the animation delay.
  • The PlayAnimationConfig.repeat property lets you optionally override the animation repeat counter.
  • The PlayAnimationConfig.repeatDelay property lets you optionally override the animation repeat delay value.
  • The PlayAnimationConfig.yoyo property lets you optionally override the animation yoyo boolean.
  • The PlayAnimationConfig.showOnStart property lets you optionally override the animation show on start value.
  • The PlayAnimationConfig.hideOnComplete property lets you optionally override the animation hide on complete value.
  • The PlayAnimationConfig.startFrame property lets you optionally set the animation frame to start on.
  • The PlayAnimationConfig.timeScale property lets you optionally set the animation time scale factor.
  • AnimationState.delayCounter is a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animation START events fire. Fix #4426 (thanks @bdaenen)
  • AnimationState.hasStarted is a new boolean property that allows you to tell if the current animation has started playing, or is still waiting for a delay to expire.
  • AnimationState.showOnStart is a new boolean property that controls if the Game Object should have setVisible(true) called on it when the animation starts.
  • AnimationState.hideOnComplete is a new boolean property that controls if the Game Object should have setVisible(false) called on it when the animation completes.
  • The AnimationState.chain method docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does!
  • The AnimationState.setDelay method has been removed. It never actually worked and you can now perform the same thing by calling either playAfterDelay or setting the delay property in the play config.
  • The AnimationState.getDelay method has been removed. You can now read the delay property directly.
  • The AnimationState.setRepeat method has been removed. You can achieve the same thing by setting the repeat property in the play config, or adjusting the public repeatCounter property if the animation has started.
  • AnimationState.handleStart is a new internal private method that handles the animation start process.
  • AnimationState.handleRepeat is a new internal private method that handles the animation repeat process.
  • AnimationState.handleStop is a new internal private method that handles the animation stop process.
  • AnimationState.handleComplete is a new internal private method that handles the animation complete process.
  • AnimationState.emitEvents is a new internal private method that emits animation events, cutting down on duplicate code.
  • The AnimationState.restart method has a new optional boolean parameter resetRepeats which controls if you want to reset the repeat counter during the restart, or not.
  • Animation.getTotalFrames is a new method that will return the total number of frames in the animation. You can access it via this.anims.currentAnim.getTotalFrames from a Sprite.
  • Animation.calculateDuration is a new method that calculates the duration, frameRate and msPerFrame for a given animation target.
  • The BuildGameObjectAnimation function now uses the PlayAnimationConfig object to set the values.
  • Sprite.playReverse is a new method that allows you to play the given animation in reverse on the Sprite.
  • Sprite.playAfterDelay is a new method that allows you to play the given animation on the Sprite after a delay.
  • Sprite.stop is a new method that allows you to stop the current animation on the Sprite.
  • AnimationManager.load has been removed as it's no longer required.
  • AnimationManager.staggerPlay has been fixed so you can now pass in negative stagger values.
  • AnimationManager.staggerPlay has a new optional boolean parameter staggerFirst, which allows you to either include or exclude the first child in the stagger calculations.
  • The Animation.completeAnimation method has been removed as it's no longer required.
  • The Animation.load method has been removed as it's no longer required.
  • The Animation.setFrame method has been removed as it's no longer required.
  • The Animation.getFirstTick method has no longer needs the includeDelay parameter, as it's handled by AnimationState now.
  • The Animation.getFrames method has a new optional boolean parameter sortFrames which will run a numeric sort on the frame names after constructing them, if a string-based frame is given.
  • Types.Animations.Animation has a new boolean property sortFrames, which lets Phaser numerically sort the generated frames.
  • AnimationState.timeScale is a new public property that replaces the old private _timeScale property.
  • AnimationState.delay is a new public property that replaces the old private _delay property.
  • AnimationState.repeat is a new public property that replaces the old private _repeat property.
  • AnimationState.repeatDelay is a new public property that replaces the old private _repeatDelay property.
  • AnimationState.yoyo is a new public property that replaces the old private _yoyo property.
  • AnimationState.inReverse is a new public property that replaces the old private _reverse property.
  • AnimationState.startAnimation is a new public method that replaces the old private _startAnimation method.
  • The AnimationState.getProgress method has been fixed so it will return correctly if the animation is playing in reverse.
  • The AnimationState.globalRemove method will now always be called when an animation is removed from the global Animation Manager, not just once.
  • The AnimationState.getRepeat method has now been removed. You can get the value from the repeat property.
  • The AnimationState.setRepeatDelay method has now been removed. You can set the value using the repeatDelay config property, or changing it at run-time.
  • AnimationState.complete is a new method that handles the completion in animation playback.
  • The AnimationState.setTimeScale method has now been removed. You can set the value using the timeScale config property, or changing it at run-time.
  • The AnimationState.getTimeScale method has now been removed. You can read the value using the timeScale property.
  • The AnimationState.getTotalFrames method has been fixed and won't error if called when no animation is loaded.
  • The AnimationState.setYoyo method has now been removed. You can set the value using the yoyo config property, or changing it at run-time.
  • The AnimationState.getYoyo method has now been removed. You can read the value using the yoyo property.
  • The AnimationState.stopAfterRepeat method now has an optional parameter repeatCount, so you can tell the animation to stop after a specified number of repeats, not just 1.
  • When playing an animation in reverse, if it reached the first frame and had to repeat, it would then jump to the frame before the final frame and carry on, skipping out the final frame.
  • The AnimationState.updateFrame method has now been removed. Everything is handled by setCurrentFrame instead, which removes one extra step out of the update process.
  • GenerateFrameNames will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers would include the __BASE frame by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.
  • GenerateFrameNumbers can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.
  • GenerateFrameNames can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.

Tilemap - New Features, Updates and API Changes

There are three large changes to Tilemaps in 3.50. If you use tilemaps, you must read this section:

1) The first change is that there are no longer DynamicTilemapLayer and StaticTilemapLayer classes. They have both been removed and replaced with the new TilemapLayer class. This new class consolidates features from both and provides a lot cleaner API experience, as well as speeding up internal logic.

In your game where you use map.createDynamicLayer or map.createStaticLayer replace it with map.createLayer instead.

2) The second change is that the Tilemap system now supports isometric, hexagonal and staggered isometric map types, along with the previous orthogonal format, thanks to a PR from @svipal. You can now export maps using any of these orientations from the Tiled Map Editor and load them into Phaser using the existing tilemap loading API. No further changes need to take place in the way your maps are loaded.

3) The Tilemap.createFromObjects method has been overhauled to make it much more useful. The method signature has changed and it now takes a new CreateFromObjectLayerConfig configuration object, or an array of them, which allows much more fine-grained control over which objects in the Tiled Object Layers are converted and what they are converted to. Previously it could only convert to Sprites, but you can now pass in a custom class, filter based on id, gid or name, even provide a Container to add the created Game Objects to. Please see the new documentation for this method and the config object for more details. Fix #3817 #4613 (thanks @georgzoeller @Secretmapper)

  • The Tilemap.createDynamicLayer method has been renamed to createLayer.
  • The Tilemap.createStaticLayer method has been removed. Use createLayer instead.
  • The Tilemap.createBlankDynamicLayer method has been renamed to createBlankLayer.
  • The Tilemap.convertLayerToStatic method has been removed as it is no longer required.
  • The TilemapLayerWebGLRenderer function will no longer iterate through the layer tilesets, drawing tiles from only that set. Instead all it does now is iterate directly through only the tiles. This allows it to take advantage of the new Multi Texturing pipeline and also draw multi-tileset isometric layers correctly.
  • Phaser.Types.Tilemaps.TilemapOrientationType is a new type def that holds the 4 types of map orientation now supported.
  • The Tile.updatePixelXY method now updates the tile XY position based on map type.
  • ParseTilesets will now correctly handle non-consecutive tile IDs. It also now correctly sets the maxId property, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)
  • Tilemap.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • LayerData.orientation is a new property that holds the tilemap layers orientation constant.
  • LayerData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • MapData.orientation is a new property that holds the tilemap layers orientation constant.
  • MapData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • Tilemaps.Components.HexagonalWorldToTileY is a new function that converts a world Y coordinate to hexagonal tile Y coordinate.
  • Tilemaps.Components.StaggeredWorldToTileY is a new function that converts a world Y coordinate to staggered tile Y coordinate.
  • Tilemaps.Components.HexagonalWorldToTileXY is a new function that converts world coordinates to hexagonal tile coordinates.
  • Tilemaps.Components.IsometricWorldToTileXY is a new function that converts world coordinates to isometric tile coordinates.
  • Tilemaps.Components.StaggeredWorldToTileXY is a new function that converts world coordinates to staggered tile coordinates.
  • Tilemaps.Components.HexagonalTileToWorldY is a new function that converts a hexagonal Y coordinate to a world coordinate.
  • Tilemaps.Components.StaggeredTileToWorldY is a new function that converts a staggered Y coordinate to a world coordinate.
  • Tilemaps.Components.HexagonalTileToWorldXY is a new function that converts hexagonal tile coordinates to world coordinates.
  • Tilemaps.Components.IsometricTileToWorldXY is a new function that converts isometric tile coordinates to world coordinates.
  • Tilemaps.Components.StaggeredTileToWorldXY is a new function that converts staggered tile coordinates to world coordinates.
  • Tilemaps.Components.GetTileToWorldXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldXXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetCullTilesFunction is a new function that returns the correct culling function to use.
  • Tilemaps.Components.HexagonalCullTiles is a new function that culls tiles in a hexagonal map.
  • Tilemaps.Components.StaggeredCullTiles is a new function that culls tiles in a staggered map.
  • Tilemaps.Components.IsometricCullTiles is a new function that culls tiles in a isometric map.
  • Tilemaps.Components.CullBounds is a new function that calculates the cull bounds for an orthogonal map.
  • Tilemaps.Components.HexagonalCullBounds is a new function that calculates the cull bounds for a hexagonal map.
  • Tilemaps.Components.StaggeredCullBounds is a new function that calculates the cull bounds for a staggered map.
  • Tilemaps.Components.RunCull is a new function that runs the culling process from the combined bounds and tilemap.
  • Tilemap._convert is a new internal private hash of tilemap conversion functions used by the public API.
  • The Tilemap._isStaticCall method has been removed and no Tilemap methods now check this, leading to faster execution.
  • The Arcade Physics Sprites vs. Tilemap Layers flow has changed. Previously, it would iterate through a whole bunch of linked functions, taking lots of jumps in the process. It now just calls the GetTilesWithinWorldXY component directly, saving lots of overhead.

Mesh Game Object - New Features, Updates and API Changes

The Mesh Game Object has been rewritten from scratch in v3.50 with a lot of changes to make it much more useful. It is accompanied by the new Geom.Mesh set of functions.

  • Geom.Mesh is a new namespace that contains the Mesh related geometry functions. These are stand-alone functions that you may, or may not require, depending on your game.
  • Geom.Mesh.Vertex is a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.
  • Geom.Mesh.Face is a new class that consists of references to the three Vertex instances that construct a single Face in a Mesh and provides methods for manipulating them.
  • Geom.Mesh.GenerateVerts is a new function that will return an array of Vertex and Face objects generated from the given data. You can provide index, or non-index vertex lists, along with UV data, normals, colors and alpha which it will parse and return the results from.
  • Geom.Mesh.GenerateGridVerts is a new function that will generate a series of Vertex objects in a grid format, based on the given GenerateGridConfig config file. You can set the size of the grid, the number of segments to split it into, translate it, color it and tile the texture across it. The resulting data can be easily used by a Mesh Game Object.
  • Geom.Mesh.GenerateObjVerts is a new function that will generate a series of Vertex objects based on the given parsed Wavefront Obj Model data. You can optionally scale and translate the generated vertices and add them to a Mesh.
  • Geom.Mesh.ParseObj is a new function that will parse a triangulated Wavefront OBJ file into model data into a format that the GenerateObjVerts function can consume.
  • Geom.Mesh.ParseObjMaterial is a new function that will parse a Wavefront material file and extract the diffuse color data from it, combining it with the parsed object data.
  • Geom.Mesh.RotateFace is a new function that will rotate a Face by a given amount, based on an optional center of rotation.
  • Loader.OBJFile is a new File Loader type that can load triangulated Wavefront OBJ files, and optionally material files, which are then parsed and stored in the OBJ Cache.
  • The Mesh constructor and MeshFactory signatures have changed to scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first. indicies is a new parameter that allows you to provide indexed vertex data to create the Mesh from, where the indicies array holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. The indicies array is optional. If your data is not indexed, then simply pass null or an empty array for this parameter.
  • The Mesh Game Object now has the Animation State Component. This allows you to create and play animations across the texture of a Mesh, something that previously wasn't possible. As a result, the Mesh now adds itself to the Update List when added to a Scene.
  • Mesh.addVertices is a new method that allows you to add vertices to a Mesh Game Object based on the given parameters. This allows you to modify a mesh post-creation, or populate it with data at a later stage.
  • Mesh.addVerticesFromObj is a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the new OBJFile with a this.load.obj call, then you can use the key with this method. This method also takes an optional scale and position parameters to control placement of the created model within the Mesh.
  • Mesh.hideCCW is a new boolean property that, when enabled, tells a Face to not render if it isn't counter-clockwise. You can use this to hide backward facing Faces.
  • Mesh.modelPosition is a new Vector3 property that allows you to translate the position of all vertices in the Mesh.
  • Mesh.modelRotation is a new Vector3 property that allows you to rotate all vertices in the Mesh.
  • Mesh.modelScale is a new Vector3 property that allows you to scale all vertices in the Mesh.
  • Mesh.panX is a new function that will translate the view position of the Mesh on the x axis.
  • Mesh.panY is a new function that will translate the view position of the Mesh on the y axis.
  • Mesh.panZ is a new function that will translate the view position of the Mesh on the z axis.
  • Mesh.setPerspective is a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.
  • Mesh.setOrtho is a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.
  • Mesh.clear is a new method that will destroy all Faces and Vertices and clear the Mesh.
  • Mesh.depthSort is a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.
  • Mesh.addVertex is a new method that allows you to add a new single Vertex into the Mesh.
  • Mesh.addFace is a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.
  • Mesh.getFaceCount new is a new method that will return the total number of Faces in the Mesh.
  • Mesh.getVertexCount new is a new method that will return the total number of Vertices in the Mesh.
  • Mesh.getFace new is a new method that will return a Face instance from the Mesh based on the given index.
  • Mesh.getFaceAt new is a new method that will return an array of Face instances from the Mesh based on the given position. The position is checked against each Face, translated through the optional Camera and Mesh matrix. If more than one Face intersects, they will all be returned but the array will be depth sorted first, so the first element will be that closest to the camera.
  • Mesh.vertices is now an array of GameObject.Vertex instances, not a Float32Array.
  • Mesh.faces is a new array of GameObject.Face instances, which is populated during a call to methods like addVertices or addModel.
  • Mesh.totalRendered is a new property that holds the total number of Faces that were rendered in the previous frame.
  • Mesh.setDebug is a new method that allows you to render a debug visualisation of the Mesh vertices to a Graphics Game Object. You can provide your own Graphics instance and optionally callback that is invoked during rendering. This allows you to easily visualise the vertices of your Mesh to help debug UV mapping.
  • The Mesh now renders by iterating through the Faces array, not the vertices. This allows you to use Array methods such as BringToTop to reposition a Face, thus changing the drawing order without having to repopulate all of the vertices. Or, for a 3D model, you can now depth sort the Faces.
  • The Mesh Game Object now extends the SingleAlpha component and the alpha value is factored into the final alpha value per vertex during rendering. This means you can now set the whole alpha across the Mesh using the standard setAlpha methods. But, if you wish to, you can still control the alpha on a per-vertex basis as well.
  • The Mesh renderer will now check to see if the pipeline capacity has been exceeded for every Face added, allowing you to use Meshes with vertex counts that exceed the pipeline capacity without causing runtime errors.
  • You can now supply just a single numerical value as the colors parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the color for all vertices created.
  • You can now supply just a single numerical value as the alphas parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the alpha for all vertices created.
  • Mesh.debugGraphic is a new property that holds the debug Graphics instance reference.
  • Mesh.debugCallback is a new property that holds the debug render callback.
  • Mesh.renderDebugVerts is a new method that acts as the default render callback for setDebug if none is provided.
  • Mesh.preDestroy is a new method that will clean-up the Mesh arrays and debug references on destruction.
  • Mesh.isDirty is a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically in preUpdate to avoid generating lots of math when nothing has changed.
  • The Mesh.uv array has been removed. All UV data is now bound in the Vertex instances.
  • The Mesh.colors array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.alphas array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.tintFill property is now a boolean and defaults to false.

Quad Game Object Removed

The Quad Game Object has been removed from v3.50.0.

You can now create your own Quads easily using the new Geom.Mesh.GenerateGridVerts function, which is far more flexible than the old quads were.

Input / Mouse Updates and API Changes

  • ScaleManager.refresh is now called when the Game.READY event fires. This fixes a bug where the Scale Manager would have the incorrect canvas bounds, because they were calculated before a previous canvas was removed from the DOM. Fix #4862 (thanks @dranitski)
  • The Game Config property inputMouseCapture has been removed, as this is now split into 3 new config options:
  • inputMousePreventDefaultDown is a new config option that allows you to control preventDefault calls specifically on mouse down events. Set it via input.mouse.preventDefaultDown in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultUp is a new config option that allows you to control preventDefault calls specifically on mouse up events. Set it via input.mouse.preventDefaultUp in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultMove is a new config option that allows you to control preventDefault calls specifically on mouse move events. Set it via input.mouse.preventDefaultMove in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultWheel is a new config option that allows you to control preventDefault calls specifically on mouse wheel events. Set it via input.mouse.preventDefaultWheel in the Game Config. It defaults to true, the same as the previous capture property did.
  • The MouseManager.capture property has been removed, as this is now split into 3 new config options (see below)
  • MouseManager.preventDefaultDown is a new boolean property, set via the inputMousePreventDefaultDown config option that allows you to toggle capture of mouse down events at runtime.
  • MouseManager.preventDefaultUp is a new boolean property, set via the inputMousePreventDefaultUp config option that allows you to toggle capture of mouse up events at runtime.
  • MouseManager.preventDefaultMove is a new boolean property, set via the inputMousePreventDefaultMove config option that allows you to toggle capture of mouse move events at runtime.
  • MouseManager.preventDefaultWheel is a new boolean property, set via the inputMousePreventDefaultWheel config option that allows you to toggle capture of mouse wheel at runtime.
  • In the MouseManager the up, down and move events are no longer set as being passive if captured. Over, Out, Wheel and the Window level Down and Up events are always flagged as being passive. Wheel events are non-passive if capturing is enabled.
  • The GamepadPlugin will now call refreshPads as part of its start process. This allows you to use Gamepads across multiple Scenes, without having to wait for a connected event from each one of them. If you've already had a connected event in a previous Scene, you can now just read the pads directly via this.input.gamepad.pad1 and similar. Fix #4890 (thanks @Sytten)
  • Shutting down the Gamepad plugin (such as when sleeping a Scene) no longer calls GamepadPlugin.disconnectAll, but destroying it does.
  • Gamepad._created is a new private internal property that keeps track of when the instance was created. This is compared to the navigator timestamp in the update loop to avoid event spamming. Fix #4890.
  • Pointer.down will now check if the browser is running under macOS and if the ctrl key was also pressed, if so, it will flag the down event as being a right-click instead of a left-click, as per macOS conventions. Fix #4245 (thanks @BigZaphod)
  • When destroying an interactive Game Object that had useHandCursor enabled, it would reset the CSS cursor to default, even if the cursor wasn't over that Game Object. It will now only reset the cursor if it's over the Game Object being destroyed. Fix #5321 (thanks @JstnPwll)
  • The InputPlugin.shutdown method will now reset the CSS cursor, in case it was set by any Game Objects in the Scene that have since been destroyed.
  • The InputPlugin.processOverEvents has had a duplicate internal loop removed from it (thanks KingCosmic)

Tint Updates and Shader Changes

Phaser has had the ability to apply an additive tint to a Game Object since the beginning, and gained 'filled tints', with and without texture alpha, in v3.11. While this was handy, it introduced a 3-way if-else condition to the shaders to handle the different modes. Plus, setting tint colors was also generating rgb order Float32 color values for each Game Object, making reading those colors back again difficult (as they'd return in BGR order).

This has all changed in 3.50, as outlined below. Tint values are now used directly in the shader and don't pass through a color conversion function first. Lots of private properties have been removed and the shaders no longer have a 3-way if-else block. All of this means improved performance and a slight reduction in memory overhead.

  • Tint.tintTopLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTL which has now been removed.
  • Tint.tintTopRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTR which has now been removed.
  • Tint.tintBottomLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBL which has now been removed.
  • Tint.tintBottomRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBR which has now been removed.
  • The property Tint._isTinted has been removed as it's no longer required.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they now read the color value as outTint.bgr instead of outTint.rgb. This allows the colors to remain in RGB order within the Tint component.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they no longer have a 3-way check on the outTintEffect value.
  • The Multi Pipeline, Bitmap Text, Render Texture, Text, TileSprite and Camera now all read the tint values from the public properties instead of the private _tintTL etc ones. They also now set the tintEffect value directly from the tintFill property, removing another conditional check.
  • The function GetColorFromValue has been removed as it's no longer used internally.
  • The Rope.tintFill property is now a boolean, not an integer, and can no longer take 2 as a value for a complete fill. Instead, you should provide a solid color texture with no alpha.
  • As a result of the change to the shader, all uses of the WebGL Util function getTintAppendFloatAlphaAndSwap have been replaced with getTintAppendFloatAlpha instead.
  • As a result of the change to the shader, the Multi Pipeline now uses the WebGLRenderer.whiteTexture and tintEffect mode of 1 by default, instead of mode 2 (which has been removed) and a transparent texture. This ensures Graphics and Shapes objects still render correctly under the new smaller shader code.
  • WebGLRenderer.whiteTexture is a new property that is a reference to a pure white 4x4 texture that is created during Boot by the Texture Manager. The Graphics Pipeline uses this internally for all geometry fill rendering.
  • The TextureManager now generates a new texture with the key __WHITE durings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines.
  • Config.images.white is a new Game Config property that specifies the 4x4 white PNG texture used by Graphics rendering. You can override this via the config, but only do so if needed.

Arcade Physics Updates

Prior to v3.50 an Arcade Physics Body could be one of two states: immovable, or moveable. An immovable body could not receive any impact from another Body. If something collided with it, it wouldn't even separate to break free from the collision (the other body had to take the full separation value). It was intended for objects such as platforms, ground or walls, there they absolutely shouldn't move under any circumstances. As a result, two immovable bodies could never be collided together. While this worked for scenery-like items, it didn't work if you required maybe 2 players who could collide with each other, but should never be able to push one another. As of 3.50 all physics bodies now have a new property pushable that allows this. A pushable body can share separation with its collider, as well as take on mass-based velocity from the impact. A non-pushable body will behave differently depending on what it collides with. For example, a pushable body hitting a non-pushable (or immoveable) body will rebound off it.

  • The Arcade Physics Body class has a new boolean property pushable (true, by default). This allows you to set if a Body can be physically pushed by another Body, or not. Fix #4175 #4415 (thanks @inmylo @CipSoft-Components)
  • Body.setPushable is a new chainable method that allows you to set the pushable state of a Body.
  • Arcade.Components.Pushable is a new component, inherited by the standard Arcade Physics Image and Sprite classes.
  • Bodies will now check to see if they are blocked in the direction they're being pushed, before resolving the collision. This helps stop some bodies from being pushed into other objects.
  • Bodies will now check which direction they were moving and separate accordingly. This helps stop some bodies from being pushed into other objects.
  • ArcadePhysics.disableUpdate is a new method that will prevent the Arcade Physics World update method from being called when the Scene updates. By disabling it, you're free to call the update method yourself, passing in your own delta and time values.
  • ArcadePhysics.enableUpdate is a new method that will make the Arcade Physics World update in time with the Scene update. This is the default, so only call this if you have specifically disabled it previously.
  • ArcadeWorldConfig.customUpdate is a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. If true the World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)
  • Physics.Arcade.Body.setCollideWorldBounds now has a new optional parameter onWorldBounds which allows you to enable the Body's onWorldBounds property in the same call (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityX is a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityY is a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)
  • The PhysicsGroup config now has two new optional properties maxVelocityX and maxVelocityY which allows you to set the maximum velocity on bodies added to the Group (thanks @samme)
  • The Arcade.Body.resetFlags method has a new optional boolean parameter clear. If set, it clears the wasTouching flags on the Body. This happens automatically when Body.reset is called. Previous to this, the flags were not reset until the next physics step (thanks @samme)
  • Physics.Arcade.ProcessX is a new set of functions, called by the SeparateX function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Physics.Arcade.ProcessY is a new set of functions, called by the SeparateY function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Arcade.Body.center values were incorrect after collisions with the world bounds or (for rectangular bodies) after collisions with another body. The body center is now updated after those separations (thanks @samme)

Loader Cache Changes

When loading any of the file types listed below it will no longer store the data file in the cache. For example, when loading a Texture Atlas using a JSON File, it used to store the parsed image data in the Texture Manager and also store the JSON in the JSON Cache under the same key. This has changed in 3.50. The data files are no longer cached, as they are not required by the textures once parsing is completed, which happens during load. This helps free-up memory. How much depends on the size of your data files. And also allows you to easily remove textures based on just their key, without also having to clear out the corresponding data cache.

  • AtlasJSONFile no longer stores the JSON in the JSON Cache once the texture has been created.
  • AtlasXMLFile no longer stores the XML in the XML Cache once the texture has been created.
  • UnityAtlasFile no longer stores the Text in the Text Cache once the texture has been created.
  • BitmapFontFile no longer stores the XML in the XML Cache once the texture has been created.
  • You can now use TextureManager.remove to remove a texture and not have to worry about clearing the corresponding JSON or XML cache entry as well in order to reload a new texture using the same key. Fix #5323 (thanks @TedGriggs)

Removal of 'resolution' property from across the API

For legacy reasons, Phaser 3 has never properly supported HighDPI devices. It will render happily to them of course, but wouldn't let you set a 'resolution' for the Canvas beyond 1. Earlier versions of 3.x had a resolution property in the Game Config, but it was never fully implemented (for example, it would break zooming cameras). When the Scale Manager was introduced in v3.16 we forced the resolution to be 1 to avoid it breaking anything else internally.

For a long time, the 'resolution' property has been present - taunting developers and confusing new comers. In this release we have finally gone through and removed all references to it. The Game Config option is now gone, it's removed from the Scale Manager, Base Camera and everywhere else where it matters. As much as we would have liked to implement the feature, we've spent too long without it, and things have been built around the assumption it isn't present. The API just wouldn't cope with having it shoe-horned in at this stage. As frustrating as this is, it's even more annoying to just leave the property there confusing people and wasting CPU cycles. Phaser 4 has been built with HighDPI screens in mind from the very start, but it's too late for v3. The following changes are a result of this removal:

  • The Phaser.Scale.Events#RESIZE event no longer sends the resolution as a parameter.
  • The BaseCamera.resolution property has been removed.
  • The internal private BaseCamera._cx, _cy, _cw and _ch properties has been removed, use x, y, width and height instead.
  • The BaseCamera.preRender method no longer receives or uses the resolution parameter.
  • The Camera.preRender method no longer receives or uses the resolution parameter.
  • The CameraManager.onResize method no longer receives or uses the resolution parameter.
  • The Core.Config.resolution property has been removed.
  • The TextStyle.resolution property is no longer read from the Game Config. You can still set it via the Text Style config to a value other than 1, but it will default to this now.
  • The CanvasRenderer no longer reads or uses the Game Config resolution property.
  • The PipelineManager.resize method along with WebGLPipeline.resize and anything else that extends them no longer receives or uses the resolution parameter.
  • The WebGLRenderer.resize and onResize methods no longer receives or uses the resolution parameter.
  • The ScaleManager.resolution property has been removed and all internal use of it.

Removed 'interpolationPercentage' parameter from all render functions

Since v3.0.0 the Game Object render functions have received a parameter called interpolationPercentage that was never used. The renderers do not calculate this value and no Game Objects apply it, so for the sake of clairty, reducing code and removing complexity from the API it has been removed from every single function that either sent or expected the parameter. This touches every single Game Object and changes the parameter order as a result, so please be aware of this if you have your own custom Game Objects, or plugins, that implement their own render methods. In terms of surface API changes, you shouldn't notice anything at all from this removal.

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.
  • You can now use this.renderer from within a Scene, as it's now a Scene-level property and part of the Injection Map.
  • Clock.addEvent can now take an existing TimerEvent object, as well as a config object. If a TimerEvent is given it will be removed from the Clock, reset and then added. This allows you to pool TimerEvents rather than constantly create and delete them. Fix #4115 (thanks @jcyuan)
  • Clock.removeEvent is a new method that allows you to remove a TimerEvent, or an array of them, from all internal lists of the current Clock.
  • Group.getMatching is a new method that will return any members of the Group that match the given criteria, such as getMatching('visible', true) (thanks @atursams)
  • Utils.Array.SortByDigits is a new function that takes the given array of strings and runs a numeric sort on it, ignoring any non-digits.
  • GroupCreateConfig, which is used when calling Group.createMultiple or Group.createFromConfig, can now accept the following new properties: setOrigin: { x, y, stepX, stepY } which are applied to the items created by the Group.
  • Transform.copyPosition is a new method that will copy the position from the given object to the Game Object (thanks @samme)
  • The Text.MeasureText function, which is used to calculate the ascent and descent of Text Game Objects whenever the style, or font size, is changed, has been updated to use the new actualBoundingBoxAscent functions present in modern browsers. This allows for significantly faster ascent calculations than previously. Older browsers, such as IE, will still fall back (thanks @rexrainbow)
  • GameObjects.GetCalcMatrix is a new function that is used to calculate the transformed Game Object matrix, based on the given Game Object, Camera and Parent. This function is now used by the following Game Objects: BitmapText (Static and Dynamic), Graphics, Extern, Mesh, Rope, Shader, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. This dramatically reduces the amount of duplicate code across the API.
  • Utils.Array.Matrix.Translate is a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.
  • Vertor3.addScale is a new method that will add the given vector and multiply it in the process.
  • When defining the ease used with a Particle Emitter you can now set easeParams in the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh)
  • BitmapMask.createMask is a new method that will internally create the WebGL textures and framebuffers required for the mask. This is now used by the constructor and if the context is lost. It now also clears any previous textures/fbos that may have been created first, helping prevent memory leaks.
  • BitmapMask.clearMask will delete any WebGL textures or framebuffers the mask is using. This is now called when the mask is destroyed, or a new mask is created upon it.
  • Quaternion now has a new property onChangeCallback which, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.
  • The Quaternion.set method has a new optional boolean parameter update (defaults to true), which will call the onChangeCallback if set.
  • Quaternion.setFromEuler is a new method that will set the quaternion from the given Euler object, optionally calling the onChangeCallback in the process.
  • Quaternion.setFromRotationMatrix is a new method that will set the rotation of the quaternion from the given Matrix4.
  • Vector3.setFromMatrixPosition is a new method that will set the components of the Vector3 based on the position of the given Matrix4.
  • Vector3.setFromMatrixColumn is a new method that will set the components of the Vector3 based on the specified Matrix4 column.
  • Vector3.fromArray is a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.
  • Vector3.min is a new method that will set the components of the Vector3 based on the Main.min between it and the given Vector3.
  • Vector3.max is a new method that will set the components of the Vector3 based on the Main.max between it and the given Vector3.
  • Vector3.addVectors is a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.
  • Vector3.addScalar is a new method that will multiply the components of the Vector3 by the scale value given.
  • Vector3.applyMatrix3 is a new method that will take a Matrix3 and apply it to the Vector3.
  • Vector3.applyMatrix4 is a new method that will take a Matrix4 and apply it to the Vector3.
  • Vector3.projectViewMatrix is a new method that multiplies the Vector3 by the given view and projection matrices.
  • Vector3.unprojectViewMatrix is a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.
  • Matrix4.setValues is a new method that allows you to set all of the matrix components individually. Most internal methods now use this.
  • Matrix.multiplyToMat4 is a new method that multiplies a Matrix4 by the given src Matrix4 and stores the results in the out Matrix4.
  • Matrix4.fromRotationXYTranslation is a new method that takes the rotation and position vectors and builds this Matrix4 from them.
  • Matrix4.getMaxScaleOnAxis is a new method that will return the maximum axis scale from the Matrix4.
  • Matrix4.lookAtRH is a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.
  • Matrix4.transform is a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.
  • Matrix4.multiplyMatrices is a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.
  • Matrix4.premultiply is a new method that takes a Matrix4 and multiplies it by the current Matrix4.
  • Matrix4.getInverse is a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.
  • CameraManager.getVisibleChildren is a new method that is called internally by the CameraManager.render method. It filters the DisplayList, so that Game Objects that pass the willRender test for the given Camera are added to a sub-list, which is then passed to the renderer. This avoids the renderer having to do any checks on the children, it just renders each one in turn.
  • Physics.Arcade.Body.setDamping is a new method that allows you to set the useDamping property of a Body in a chainable way. Fix #5352 (thanks @juanitogan)
  • The GameObjects.Graphics.fillGradientStyle method can now accept a different alpha value for each of the fill colors. The default is still 1. If you only provide a single alpha, it'll be used for all colors. Fix #5044 (thanks @zhangciwu)
  • Types.Core.PipelineConfig is a new configuration object that you can set in the Game Config under the pipeline property. It allows you to define custom WebGL pipelines as part of the Game Config, so they're automatically installed and ready for use by all Scenes in your game. You can either set the pipeline object, or set it under the render sub-config.
  • Utils.Object.DeepCopy is a new function that will recursively deep copy an array of object.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Earcut has now been exposed and is available via Geom.Polygon.Earcut and is fully documented.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.
  • Pointer.downTime now stores the event timestamp of when the first button on the input device was pressed down, not just when button 1 was pressed down.
  • Pointer.upTime now stores the event timestamp of when the final depressed button on the input device was released, not just when button 1 was released.
  • The Pointer.getDuration method now uses the new Pointer downTime and upTime values, meaning it will accurately report the duration of when any button is being held down, not just the primary one. Fix #5112 (thanks @veleek)
  • The BaseShader default vertex shader now includes the outTexCoord vec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok)
  • When using the GameObjectCreator for Containers you can now specify the children property in the configuration object.
  • Textures.Parsers.JSONHash will now perform a hasOwnProperty check when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes from JSON.parse. Fix #4768 (thanks @RollinSafary)
  • The Camera3D Plugin has been rebuilt for Phaser 3.50 and the webpack config updated. This plugin is now considered deprecated and will not be updated beyond this release.
  • Tween.seek will no longer issue a console warning for 'Tween.seek duration too long', it's now up to you to check on the performance of tween seeking.
  • If inputWindowEvents is set in the Game Config, then the MouseManager will now listen for the events on window.top instead of just window, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in a try/catch block, as not all sites allow access to window.top (specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow)
  • MouseManager.isTop is a new boolean read-only property that flags if the mouse event listeners were attached to window.top (true), or just window (false). By default Phaser will attempt window.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back to window in those cases and set this property to false (thanks BunBunBun)
  • Types.GameObjects.Text.GetTextSizeObject is a new type def for the GetTextSize function results.
  • Utils.Array.StableSort has been recoded. It's now based on Two-Screens stable sort 0.1.8 and has been updated to fit into Phaser better and no longer create any window bound objects. The inplace function has been removed, just call StableSort(array) directly now. All classes that used StableSort.inplace have been updated to call it directly.
  • If a Scene is paused, or sent to sleep, it will automatically call Keyboard.resetKeys. This means that if you hold a key down, then sleep or pause a Scene, then release the key and resume or wake the Scene, it will no longer think it is still being held down (thanks @samme)
  • Actions.setOrigin will now call updateDisplayOrigin on the items array, otherwise the effects can't be seen when rendering.
  • You can now set the ArcadeWorld.fixedStep property via the ArcadeWorldConfig object (thanks @samme)
  • Utils.Array.NumerArray can now accept the start and end parameters in reverse order, i.e. 10, 1 will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.
  • DataManager.Events.DESTROY is a new event that the Data Manager will listen for from its parent and then call its own destroy method when received.
  • The Quaternion class constructor will now default the values to 0,0,0,1 if they're not provided, making it an identity quaternion, rather than the 0,0,0,0 it was before.
  • You can now set the ParticleEmitter.reserve value via the emitter configuration object (thanks @vforsh)
  • Setting the pixelArt config option will now set antialiasGL to false, as well as antialias. Fix #5309 (thanks @Vegita2)
  • The Shape class now includes the ComputedSize component properties and methods directly in the class, rather than applying as a mixin. setSize is now flagged as being private, because it shouldn't be used on Shape classes, which was leading to confusion as it appeared in the public-facing API. Fix #4811 (thanks @aolsx)
  • The Loader.maxParallelDownloads value is now set to 6 if running on Android, or 32 on any other OS. This avoids net::ERR_FAILED issues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary)
  • When running an Arcade Physics overlap test against a StaticBody, it will no longer set the blocked states of the dynamic body. If you are doing a collision test, they will still be set, but they're skipped for overlap-only tests. Fix #4435 (thanks @samme)
  • The Line Game Object will now default its width and height to 1, rather than zero. This allows you to give Line objects a physics body (although you will still need to re-adjust the center of the body manually). Fix #4596 (thanks @andrewaustin)
  • Internally, the Quaternion class now has 4 new private properties: _x, _y, _z and _w and 4 new getters and setters for the public versions. It also now passes most methods via set to allow for the onChange callback to be invoked. This does not change the public-facing API.
  • Group now extends EventEmitter, allowing you to emit custom events from within a Group.
  • Device.Audio.wav now uses audio/wav as the canPlayType check string, instead of audio/wav; codecs="1", which should allow iOS13 to play wav files again.
  • In the Loader.FileTypes.TextFile config you can now override the type and cache destination for the file.
  • Loader.MultiFile will now parse the given files array and only add valid entries into the file list, allowing multifiles to now have optional file entries.
  • The ParticleEmitter.tint value is now 0xffffff (previously, it was 0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh)
  • SceneManager.start will now reset the SceneSystems.sceneUpdate reference to NOOP. This gets set back to the Scene update method again during bootScene (if it has one) and stops errors with external plugins and multi-part files that may trigger update before create has been called. Fix #4629 (thanks @Osmose)
  • Phaser.Scene.renderer is a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.
  • The CanvasRenderer._tempMatrix1, _tempMatrtix2, _tempMatrix3 and _tempMatrix4 properties have been removed. They were all flagged as private, yet used in lots of places. Instead, Game Objects now manager their own matrices, or use the global GetCalcMatrix function instead.

Bug Fixes

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)
  • The GridAlign action didn't work if only the height parameter was set. Fix #5019 (thanks @halilcakar)
  • The Color.HSVToRGB function has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX)
  • Previously, the easeParams array within a Tweens props object, or a multi-object tween, were ignored and it was only used if set on the root Tween object. It will now work correctly set at any depth. Fix #4292 (thanks @willblackmore)
  • When using Camera.setRenderToTexture its zoom and rotation values would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok)
  • GameObjects.Shape.Grid would render a white fill even if you passed undefined as the fill color in the constructor. It now doesn't render cells if no fill color is given.
  • The onMouse events in the Input Manager didn't reset the activePointer property to the mouse, meaning on dual-input systems such as Touch Screen devices, the active pointer would become locked to whichever input method was used first. Fix #4615 #5232 (thanks @mmolina01 @JstnPwll @Legomite)
  • The Scale Managers GetScreenOrientation function will now check for window.orientation first, because iOS mobile browsers have an incomplete implementation of the Screen API, forcing us to use the window value as a priority. This means the Scale Manager will now emit orientationchange events correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu)
  • Time.Clock.addEvent can now take an instance of a TimerEvent as its parameter. Fix #5294 (thanks @samme @EmilSV)
  • GameConfig.audio now defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)
  • The Loader.path was being added to the File URL even if the URL was absolute. This is now checked for and the path is not applied unless the URL is relative (thanks @firesoft)
  • Group.getMatching would always return an empty array. It now returns matching children (thanks @samme)
  • The ParticleManagerWebGLRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in follow offsets separately. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers. Fix #5319 #5195 #4739 #4691 (thanks @vforsh @condeagustin @IvanDem @Formic)
  • The ParticleManagerCanvasRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also uses setToContext internally. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers, or having the Camera zoomed, running under Canvas. Fix #4908 #4531 #4131 (thanks @smjnab @SirLink @jhooper04)
  • The Graphics WebGL Renderer will now default to pathOpen = true. This fixes issues under WebGL where, for example, adding an arc and calling strokePath, without first calling beginPath will no longer cause rendering artefacts when WebGL tries to close the path with a single tri.
  • Graphics.strokeRoundedRect now issues moveTo commands as part of the drawing sequence, preventing issues under WebGL where on older Android devices it would project additional vertices into the display. Fix #3955 (thanks @alexeymolchan)
  • Creating a Bitmap Mask from a texture atlas that was then used to mask another Game Object also using that same texture atlas would throw the error GL_INVALID_OPERATION : glDrawArrays: Source and destination textures of the draw are the same.. It now renders as expected. Fix #4675 (thanks @JacobCaron)
  • When using the same asset for a Game Object to be used as a mask, it would make other Game Objects using the same asset, that appeared above the mask in the display list, to not render. Fix #4767 (thanks @smjnab)
  • When taking a snapshot in WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in the WebGLSnapshot function. Fix #4956 (thanks @gammafp @telinc1)
  • You can now draw a Group to a RenderTexture. Previously, it failed to pass the camera across, resulting in none of the Group children being drawn. Fix #5330 (thanks @somnolik)
  • Particles.EmitterOp.setMethods will now reset both onEmit and onUpdate to their default values. This allows you to reconfigure an emitter op with a new type of value and not have it stuck on the previous one. Fix #3663 (thanks @samme)
  • Particles.EmitterOp now cleanly separates between the different types of property configuration options. start | end will now ease between the two values, min | max will pick a random value between them and random: [] will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)
  • When setting both transparent: true and backgroundColor in the Game Config, it would ignore the transparency and use the color anyway. If transparent, the game is now fully transparent. Fix #5362 (thanks @Hoshinokoe)

Namespace Updates

  • The Phaser.Curves.MoveTo function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.DOM.GetInnerHeight function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Bob class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsManager class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsPlugin class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Particles.EmitterOp class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.GetTextSize function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.MeasureText function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.TextStyle function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Input.CreatePixelPerfectHandler function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapCirc function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapRect function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Tilemap namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Components namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.MatterGameObject class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.PointerConstraint class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetPhysicsPlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetScenePlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Structs.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Tilemaps.Parsers.Tiled function has now been exposed on the Phaser namespace (thanks @samme)
  • Every single Tilemap.Component function has now been made public. This means you can call the Component functions directly, should you need to, outside of the Tilemap system.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360 @volkans80 @jaabberwocky @maikthomas @atursams @LearningCode2023 @DylanC @BenjaminDRichards @rexrainbow @Riderrr @spwilson2 @EmilSV @PhaserEditor2D @Gangryong @vinerz @trynx @usufruct99 @pirateksh

- JavaScript
Published by photonstorm over 5 years ago

phaser - Phaser v3.50.0 Beta 9

Version 3.50.0 - Subaru - in development

WebGL Pipeline Updates

If you use a custom WebGL Pipeline in your game, you must update your code in order to use Phaser 3.50.

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

Other pipeline changes are as follows:

  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.
  • The WebGLPipeline.shouldFlush method now accepts an optional parameter amount. If given, it will return true if when the amount is added to the vertex count it will exceed the vertex capacity. The Multi Pipeline has been updated to now use this method instead of performing the comparison multiple times itself.
  • The RopePipeline now extends MultiPipeline and just changes the topolgy, vastly reducing the filesize.

Pipeline Uniform Changes

Piplines now have a new uniforms array that can be passed in with the config. All default pipelines now set these. The array contains the names, as strings, of all uniforms your pipeline shader uses. Once the pipeline shader has been successfully linked, it will use the array of names to look-up the WebGLUniformLocation of all uniforms specified. These are stored in the new WebGLPipeline.uniforms object. This takes place in the new WebGLPipeline.setUniformLocations method.

When a pipeline is bound, you can now use the new methods (listed below) to set uniform values directly on the pipeline. Previously, calling a method such as setFloat3 on a pipeline would pass that call over to WebGLRenderer. The renderer would first check to see if the pipeline program was current, and if not, make it so, before then looking up the uniform location and finally setting it. This is a lot of steps to take for pipelines that potentially need to change uniforms for every Game Object they render.

Under the new methods, and using the new pre-cached uniform locations, these extra steps are skipped. The uniform value is set directly, no shader binding takes place and no location look-up happens. This dramatically reduces the number of WebGL ops being issued per frame. To clearly differentiate these pipline methods, we have renamed them. The new method names are as follows:

  • WebGLPipeline.set1f will set a 1f uniform based on the given name.
  • WebGLPipeline.set2f will set a 2f uniform based on the given name.
  • WebGLPipeline.set3f will set a 3f uniform based on the given name.
  • WebGLPipeline.set4f will set a 4f uniform based on the given name.
  • WebGLPipeline.set1fv will set a 1fv uniform based on the given name.
  • WebGLPipeline.set2fv will set a 2fv uniform based on the given name.
  • WebGLPipeline.set3fv will set a 3fv uniform based on the given name.
  • WebGLPipeline.set4fv will set a 4fv uniform based on the given name.
  • WebGLPipeline.set1iv will set a 1iv uniform based on the given name.
  • WebGLPipeline.set2iv will set a 2iv uniform based on the given name.
  • WebGLPipeline.set3iv will set a 3iv uniform based on the given name.
  • WebGLPipeline.set4iv will set a 4iv uniform based on the given name.
  • WebGLPipeline.set1i will set a 1i uniform based on the given name.
  • WebGLPipeline.set2i will set a 2i uniform based on the given name.
  • WebGLPipeline.set3i will set a 3i uniform based on the given name.
  • WebGLPipeline.set4i will set a 4i uniform based on the given name.
  • WebGLPipeline.setMatrix2fv will set a matrix 2fv uniform based on the given name.
  • WebGLPipeline.setMatrix3fv will set a matrix 3fv uniform based on the given name.
  • WebGLPipeline.setMatrix4fv will set a matrix 4fv uniform based on the given name.

If your code uses any of the old method names, please update them using the list below:

  • WebGLPipeline.setFloat1 has been removed. Please use set1f instead.
  • WebGLPipeline.setFloat2 has been removed. Please use set2f instead.
  • WebGLPipeline.setFloat3 has been removed. Please use set3f instead.
  • WebGLPipeline.setFloat4 has been removed. Please use set4f instead.
  • WebGLPipeline.setFloat1v has been removed. Please use set1fv instead.
  • WebGLPipeline.setFloat2v has been removed. Please use set2fv instead.
  • WebGLPipeline.setFloat3v has been removed. Please use set3fv instead.
  • WebGLPipeline.setFloat4v has been removed. Please use set4fv instead.
  • WebGLPipeline.setInt1 has been removed. Please use set1i instead.
  • WebGLPipeline.setInt2 has been removed. Please use set2i instead.
  • WebGLPipeline.setInt3 has been removed. Please use set3i instead.
  • WebGLPipeline.setInt4 has been removed. Please use set4i instead.
  • WebGLPipeline.setMatrix1 has been removed. Please use setMatrix2fv instead.
  • WebGLPipeline.setMatrix2 has been removed. Please use setMatrix3fv instead.
  • WebGLPipeline.setMatrix3 has been removed. Please use setMatrix4fv instead.

Pipeline Manager

The WebGL.PipelineManager is a new class that is responsbile for managing all of the WebGL Pipelines in Phaser. An instance of the Pipeline Manager is created by the WebGL Renderer and is available under the pipelines property. This means that the WebGL Renderer no longer handles pipelines directly, causing the following API changes:

  • WebGLRenderer.pipelines is no longer a plain object containing pipeline instances. It's now an instance of the PipelineManager class. This instance is created during the init and boot phase of the renderer.
  • The WebGLRenderer.currentPipeline property no longer exists, instead use PipelineManager.current.
  • The WebGLRenderer.previousPipeline property no longer exists, instead use PipelineManager.previous.
  • The WebGLRenderer.hasPipeline method no longer exists, instead use PipelineManager.has.
  • The WebGLRenderer.getPipeline method no longer exists, instead use PipelineManager.get.
  • The WebGLRenderer.removePipeline method no longer exists, instead use PipelineManager.remove.
  • The WebGLRenderer.addPipeline method no longer exists, instead use PipelineManager.add.
  • The WebGLRenderer.setPipeline method no longer exists, instead use PipelineManager.set.
  • The WebGLRenderer.rebindPipeline method no longer exists, instead use PipelineManager.rebind.
  • The WebGLRenderer.clearPipeline method no longer exists, instead use PipelineManager.clear.

The Pipeline Manager also offers the following new features:

  • The PipelineManager.resize method automatically handles resize events across all pipelines.
  • The PipelineManager.preRender method calls the pre-render method of all pipelines.
  • The PipelineManager.render method calls the render method of all pipelines.
  • The PipelineManager.postRender method calls the post-render method of all pipelines.
  • The PipelineManager.setMulti method automatically binds the Multi Texture Pipeline, Phaser's default.
  • The PipelineManager.clear method will clear the pipeline, store it in previous and free the renderer.
  • The PipelineManager.rebind method will reset the rendering context and restore the previous pipeline, if set.

New constants have been created to help you reference a pipeline without needing to use strings:

  • Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE for the Bitmap Mask Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE for the Light 2D Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE for the Single Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE for the Multi Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE for the Rope Pipeline.

All Game Objects have been updated to use the new constants and Pipeline Manager.

Single Pipeline

There is also a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGL Multi-Texture Rendering

The Multi Pipeline (previously called the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw-call bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLPipeline.forceZero is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.

Light Pipeline Changes

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh and Quad Game Objects now support rendering with normal maps.
  • The Graphics Game Objects now support rendering in Light2d. You can even use normal map textures for the texture fills.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • All Shape Game Objects (Rectangle, IsoBox, Star, Polygon, etc) now support rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Both Static and Dynamic Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Lights

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

WebGL ModelViewProjection API Changes

The ModelViewProjection object contained a lot of functions that Phaser never used internally. These have now been moved to external functions, which can be easily excluded from Custom builds to save space.

If you used any of them in your code, please update to the new function names below:

  • Phaser.Renderer.WebGL.MVP is a new namespace under which the Model View Projection functions now live.
  • projIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectIdentity
  • projPersp is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectPerspective
  • modelRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateX
  • modelRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateY
  • modelRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateZ
  • viewLoad is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad
  • viewRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateX
  • viewRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateY
  • viewRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateZ
  • viewScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewScale
  • viewTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewTranslate
  • modelIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Identity
  • modelScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Scale
  • modelTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Translate
  • viewIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewIdentity
  • viewLoad2D is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad2D
  • projOrtho is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectOrtho
  • Phaser.Renderer.WebGL.MVP.SetIdentity is a new function the others use, to save on space.

BitmapText - New Features, Updates and API Changes

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.
  • You can now use setMaxWidth on DynamicBitmapText, which wasn't previously possible. Fix #4997 (thanks @AndreaBoeAbrahamsen)

Update List Changes

The way in which Game Objects add themselves to the Scene Update List has changed. Instead of being added by the Factory methods, they will now add and remove themselves based on the new ADDED_TO_SCENE and REMOVED_FROM_SCENE events. This means, you can now add Sprites directly to a Container, or Group, and they'll animate properly without first having to be part of the Display List. The full set of changes and new features relating to this follow:

  • GameObjects.Events.ADDED_TO_SCENE is a new event, emitted by a Game Object, when it is added to a Scene, or a Container that is part of the Scene.
  • GameObjects.Events.REMOVED_FROM_SCENE is a new event, emitted by a Game Object, when it is removed from a Scene, or a Container that is part of the Scene.
  • Scenes.Events.ADDED_TO_SCENE is a new event, emitted by a Scene, when a new Game Object is added to the display list in the Scene, or a Container that is on the display list.
  • Scenes.Events.REMOVED_FROM_SCENE is a new event, emitted by a Scene, when it a Game Object is removed from the display list in the Scene, or a Container that is on the display list.
  • GameObject.addedToScene is a new method that custom Game Objects can use to perform additional set-up when a Game Object is added to a Scene. For example, Sprite uses this to add itself to the Update List.
  • GameObject.removedFromScene is a new method that custom Game Objects can use to perform additional tear-down when a Game Object is removed from a Scene. For example, Sprite uses this to remove themselves from the Update List.
  • Game Objects no longer automatically remove themselves from the Update List during preDestroy. This should be handled directly in the removedFromScene method now.
  • The Container will now test to see if any Game Object added to it is already on the display list, or not, and emit its ADDED and REMOVED events accordingly. Fix #5267 #3876 (thanks @halgorithm @mbpictures)
  • DisplayList.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • DisplayList.addChildCallback is a new method that overrides the List callback and fires the new ADDED events.
  • DisplayList.removeChildCallback is a new method that overrides the List callback and fires the new REMOVED events.
  • GameObjectCreator.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • GameObjectFactory.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • ProcessQueue.checkQueue is a new boolean property that will make sure only unique objects are added to the Process Queue.
  • The Update List now uses the new checkQueue property to ensure no duplicate objects are on the active list.
  • DOMElementFactory, ExternFactory, ParticleManagerFactor, RopeFactory and SpriteFactory all no longer add the objects to the Update List, this is now handled by the ADDED events instead.
  • Sprite, Rope, ParticleEmitterManager, Extern and DOMElement now all override the addedToScene and removedFromScene callbacks to handle further set-up tasks.

Spine Plugin Updates

  • The Spine Runtimes have been updated to 3.8.99, which are the most recent non-beta versions. Please note, you will need to re-export your animations if you're working in a version of Spine lower than 3.8.20.
  • SpineContainer is a new Game Object available via this.add.spineContainer to which you can add Spine Game Objects only. It uses a special rendering function to retain batching, even across multiple container or Spine Game Object instances, resulting in dramatically improved performance over using regular Containers.
  • A Spine Game Object with setVisible(false) will no longer still cause internal gl commands and is now properly skipped, retaining any current batch in the process. Fix #5174 (thanks @Kitsee)
  • The Spine Game Object WebGL Renderer will no longer clear the type if invisible and will only end the batch if the next type doesn't match.
  • The Spine Game Object WebGL Renderer will no longer rebind the pipeline if it was the final object on the display list, saving lots of gl commands.
  • The Webpack build scripts have all been updated for Webpack 4.44.x. Fix #5243 (thanks @RollinSafary)
  • There is a new npm script npm run plugin.spine.runtimes which will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo into plugins/spine/ in order for this to work and then run npm i.
  • Spine Game Objects can now be rendered to Render Textures. Fix #5184 (thanks @Kitsee)
  • Using > 128 Spine objects in a Container would cause a WebGL: INVALID_OPERATION: vertexAttribPointer: no ARRAY_BUFFER is bound and offset is non-zero error if you added any subsequent Spine objects to the Scene. There is now no limit. Fix #5246 (thanks @d7561985)
  • The Spine Plugin will now work in HEADLESS mode without crashing. Fix #4988 (thanks @raimon-segura)
  • Spine Game Objects now use -1 as their default blend mode, which means 'skip setting it'.
  • The Spine TypeScript defs have been updated for the latest version of the plugin and to add SpineContainers.
  • The SpineGameObject.setAnimation method will now use the trackIndex parameter if ignoreIfPlaying is set and run the check against this track index. Fix #4842 (thanks @vinerz)
  • The SpineFile will no longer throw a warning if adding a texture into the Texture Manager that already exists. This allows you to have multiple Spine JSON use the same texture file, however, it also means you now get no warning if you accidentally load a texture that exists, so be careful with your keys! Fix #4947 (thanks @Nomy1)
  • The Spine Plugin destroy method will now no longer remove the Game Objects from the Game Object Factory, or dispose of the Scene Renderer. This means when a Scene is destroyed, it will keep the Game Objects in the factory for other Scene's to use. Fix #5279 (thanks @Racoonacoon)
  • SpinePlugin.gameDestroy is a new method that is called if the Game instance emits a destroy event. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.
  • SpineFile will now check to see if another identical atlas in the load queue is already loading the texture it needs and will no longer get locked waiting for a file that will never complete. This allows multiple skeleton JSONs to use the same atlas data. Fix #5331 (thanks @Racoonacoon)
  • SpineFile now uses a ! character to split the keys, instead of an underscore, preventing the plugin from incorrectly working out the keys for filenames with underscores in them. Fix #5336 (thanks @Racoonacoon)

Animation API - New Features and Updates

If you use Animations in your game, please read the following important API changes in 3.50:

The Animation API has had a significant overhaul to improve playback handling. Instead of just playing an animation based on its global key, you can now supply a new PlayAnimationConfig object instead, which allows you to override any of the default animation settings, such as duration, delay and yoyo (see below for the full list). This means you no longer have to create lots of duplicate animations just to change properties such as duration, and can now set them dynamically at run-time as well.

  • The Animation class no longer extends EventEmitter, as it no longer emits any events directly. This means you cannot now listen for events directly from an Animation instance. All of the events are now dispatched by the Game Objects instead.
  • All of the SPRITE_ANIMATION_KEY events have been removed. Instead, please use the new events which all carry the frameKey parameter, which can be used to handle frame specific events. The only exception to this is ANIMATION_COMPLETE_KEY, which is a key specific version of the completion event.
  • ANIMATION_UPDATE_EVENT is a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.
  • ANIMATION_STOP_EVENT is a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of the stop methods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)
  • The Game Object Component.Animation component has been renamed to AnimationState and has moved namespace. It's now in Phaser.Animations instead of GameObjects.Components to help differentiate it from the Animation class when browsing the documentation.
  • The play, playReverse, playAfterDelay, playAfterRepeat and chain Sprite and Animation Component methods can now all take a Phaser.Types.Animations.PlayAnimationConfig configuration object, as well as a string, as the key parameter. This allows you to override any default animation setting with those defined in the config, giving you far greater control over animations on a Game Object level, without needing to globally duplicate them.
  • AnimationState.create is a new method that allows you to create animations directly on a Sprite. These are not global and never enter the Animation Manager, instead risiding within the Sprite itself. This allows you to use the same keys across both local and global animations and set-up Sprite specific local animations.
  • AnimationState.generateFrameNumbers is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • AnimationState.generateFrameNames is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • All playback methods: play, playReverse, playAfterDelay and playAfterRepeat will now check to see if the given animation key exists locally on the Sprite first. If it does, it's used, otherwise it then checks the global Animation Manager for the key instead.
  • AnimationState.skipMissedFrames is now used when playing an animation, allowing you to create animations that run at frame rates far exceeding the refresh rate, or that will update to the correct frame should the game lag. Feature #4232 (thanks @colorcube)
  • AnimationManager.addMix is a new method that allows you to create mixes 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.
  • AnimationManager.getMix is a new method that will return the mix duration between the two given animations.
  • AnimationManager.removeMix is a new method that will remove the mixture between either two animations, or all mixtures for the given animation.
  • AnimationState.remove is a new method that will remove a locally stored Animation instance from a Sprite.
  • AnimationState.get is a new method that will return a locally stored Animation instance from the Sprite.
  • AnimationState.exists is a new method that will check if a locally stored Animation exists on the Sprite.
  • The internal AnimationState.remove method has been renamed to globalRemove.
  • AnimationState.textureManager is a new property that references the global Texture Manager.
  • AnimationState.anims is a new property that contains locally created Animations in a Custom Map.
  • AnimationState.play and Sprite.play no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • AnimationState.playReverse and Sprite.playReverse no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • The AnimationState.delayedPlay method has been renamed to playAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration.
  • The AnimationState.stopOnRepeat method has been renamed to stopAfterRepeat
  • The AnimationState.getCurrentKey method has been renamed to getName.
  • AnimationState.getFrameName is a new method that will return the key of the current Animation Frame, if an animation has been loaded.
  • AnimationState.playAfterDelay and Sprite.playAfterDelay are new methods that will play the given animation after the delay in ms expires.
  • AnimationState.playAfterRepeat and Sprite.playAfterRepeat are new methods that will play the given animation after the current animation finishes repeating. You can also specify the number of repeats allowed left to run.
  • The AnimationState.chain method is now available on the Sprite class.
  • The AnimationState.stopAfterDelay method is now available on the Sprite class.
  • The AnimationState.stopAfterRepeat method is now available on the Sprite class.
  • The AnimationState.stopOnFrame method is now available on the Sprite class.
  • AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser. Please see the comprehensive documentation for this method for full details on how to do this.
  • AnimationState now handles all of the loading of the animation. It no longer has to make calls out to the Animation Manager or Animation instance itself and will load the animation data directly, replacing as required from the optional PlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.
  • The PlayAnimationConfig.frameRate property lets you optionally override the animation frame rate.
  • The PlayAnimationConfig.duration property lets you optionally override the animation duration.
  • The PlayAnimationConfig.delay property lets you optionally override the animation delay.
  • The PlayAnimationConfig.repeat property lets you optionally override the animation repeat counter.
  • The PlayAnimationConfig.repeatDelay property lets you optionally override the animation repeat delay value.
  • The PlayAnimationConfig.yoyo property lets you optionally override the animation yoyo boolean.
  • The PlayAnimationConfig.showOnStart property lets you optionally override the animation show on start value.
  • The PlayAnimationConfig.hideOnComplete property lets you optionally override the animation hide on complete value.
  • The PlayAnimationConfig.startFrame property lets you optionally set the animation frame to start on.
  • The PlayAnimationConfig.timeScale property lets you optionally set the animation time scale factor.
  • AnimationState.delayCounter is a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animation START events fire. Fix #4426 (thanks @bdaenen)
  • AnimationState.hasStarted is a new boolean property that allows you to tell if the current animation has started playing, or is still waiting for a delay to expire.
  • AnimationState.showOnStart is a new boolean property that controls if the Game Object should have setVisible(true) called on it when the animation starts.
  • AnimationState.hideOnComplete is a new boolean property that controls if the Game Object should have setVisible(false) called on it when the animation completes.
  • The AnimationState.chain method docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does!
  • The AnimationState.setDelay method has been removed. It never actually worked and you can now perform the same thing by calling either playAfterDelay or setting the delay property in the play config.
  • The AnimationState.getDelay method has been removed. You can now read the delay property directly.
  • The AnimationState.setRepeat method has been removed. You can achieve the same thing by setting the repeat property in the play config, or adjusting the public repeatCounter property if the animation has started.
  • AnimationState.handleStart is a new internal private method that handles the animation start process.
  • AnimationState.handleRepeat is a new internal private method that handles the animation repeat process.
  • AnimationState.handleStop is a new internal private method that handles the animation stop process.
  • AnimationState.handleComplete is a new internal private method that handles the animation complete process.
  • AnimationState.emitEvents is a new internal private method that emits animation events, cutting down on duplicate code.
  • The AnimationState.restart method has a new optional boolean parameter resetRepeats which controls if you want to reset the repeat counter during the restart, or not.
  • Animation.getTotalFrames is a new method that will return the total number of frames in the animation. You can access it via this.anims.currentAnim.getTotalFrames from a Sprite.
  • Animation.calculateDuration is a new method that calculates the duration, frameRate and msPerFrame for a given animation target.
  • The BuildGameObjectAnimation function now uses the PlayAnimationConfig object to set the values.
  • Sprite.playReverse is a new method that allows you to play the given animation in reverse on the Sprite.
  • Sprite.playAfterDelay is a new method that allows you to play the given animation on the Sprite after a delay.
  • Sprite.stop is a new method that allows you to stop the current animation on the Sprite.
  • AnimationManager.load has been removed as it's no longer required.
  • AnimationManager.staggerPlay has been fixed so you can now pass in negative stagger values.
  • AnimationManager.staggerPlay has a new optional boolean parameter staggerFirst, which allows you to either include or exclude the first child in the stagger calculations.
  • The Animation.completeAnimation method has been removed as it's no longer required.
  • The Animation.load method has been removed as it's no longer required.
  • The Animation.setFrame method has been removed as it's no longer required.
  • The Animation.getFirstTick method has no longer needs the includeDelay parameter, as it's handled by AnimationState now.
  • The Animation.getFrames method has a new optional boolean parameter sortFrames which will run a numeric sort on the frame names after constructing them, if a string-based frame is given.
  • Types.Animations.Animation has a new boolean property sortFrames, which lets Phaser numerically sort the generated frames.
  • AnimationState.timeScale is a new public property that replaces the old private _timeScale property.
  • AnimationState.delay is a new public property that replaces the old private _delay property.
  • AnimationState.repeat is a new public property that replaces the old private _repeat property.
  • AnimationState.repeatDelay is a new public property that replaces the old private _repeatDelay property.
  • AnimationState.yoyo is a new public property that replaces the old private _yoyo property.
  • AnimationState.inReverse is a new public property that replaces the old private _reverse property.
  • AnimationState.startAnimation is a new public method that replaces the old private _startAnimation method.
  • The AnimationState.getProgress method has been fixed so it will return correctly if the animation is playing in reverse.
  • The AnimationState.globalRemove method will now always be called when an animation is removed from the global Animation Manager, not just once.
  • The AnimationState.getRepeat method has now been removed. You can get the value from the repeat property.
  • The AnimationState.setRepeatDelay method has now been removed. You can set the value using the repeatDelay config property, or changing it at run-time.
  • AnimationState.complete is a new method that handles the completion in animation playback.
  • The AnimationState.setTimeScale method has now been removed. You can set the value using the timeScale config property, or changing it at run-time.
  • The AnimationState.getTimeScale method has now been removed. You can read the value using the timeScale property.
  • The AnimationState.getTotalFrames method has been fixed and won't error if called when no animation is loaded.
  • The AnimationState.setYoyo method has now been removed. You can set the value using the yoyo config property, or changing it at run-time.
  • The AnimationState.getYoyo method has now been removed. You can read the value using the yoyo property.
  • The AnimationState.stopAfterRepeat method now has an optional parameter repeatCount, so you can tell the animation to stop after a specified number of repeats, not just 1.
  • When playing an animation in reverse, if it reached the first frame and had to repeat, it would then jump to the frame before the final frame and carry on, skipping out the final frame.
  • The AnimationState.updateFrame method has now been removed. Everything is handled by setCurrentFrame instead, which removes one extra step out of the update process.
  • GenerateFrameNames will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers would include the __BASE frame by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.
  • GenerateFrameNumbers can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.
  • GenerateFrameNames can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.

Tilemap - New Features, Updates and API Changes

There are three large changes to Tilemaps in 3.50. If you use tilemaps, you must read this section:

1) The first change is that there are no longer DynamicTilemapLayer and StaticTilemapLayer classes. They have both been removed and replaced with the new TilemapLayer class. This new class consolidates features from both and provides a lot cleaner API experience, as well as speeding up internal logic.

In your game where you use map.createDynamicLayer or map.createStaticLayer replace it with map.createLayer instead.

2) The second change is that the Tilemap system now supports isometric, hexagonal and staggered isometric map types, along with the previous orthogonal format, thanks to a PR from @svipal. You can now export maps using any of these orientations from the Tiled Map Editor and load them into Phaser using the existing tilemap loading API. No further changes need to take place in the way your maps are loaded.

3) The Tilemap.createFromObjects method has been overhauled to make it much more useful. The method signature has changed and it now takes a new CreateFromObjectLayerConfig configuration object, or an array of them, which allows much more fine-grained control over which objects in the Tiled Object Layers are converted and what they are converted to. Previously it could only convert to Sprites, but you can now pass in a custom class, filter based on id, gid or name, even provide a Container to add the created Game Objects in to. Please see the new documentation for this method and the config object for more details. Fix #3817 #4613 (thanks @georgzoeller @Secretmapper)

  • The Tilemap.createDynamicLayer method has been renamed to createLayer.
  • The Tilemap.createStaticLayer method has been removed. Use createLayer instead.
  • The Tilemap.createBlankDynamicLayer method has been renamed to createBlankLayer.
  • The Tilemap.convertLayerToStatic method has been removed as it is no longer required.
  • The TilemapLayerWebGLRenderer function will no longer iterate through the layer tilesets, drawing tiles from only that set. Instead all it does now is iterate directly through only the tiles. This allows it to take advantage of the new Multi Texturing pipeline and also draw multi-tileset isometric layers correctly.
  • Phaser.Types.Tilemaps.TilemapOrientationType is a new type def that holds the 4 types of map orientation now supported.
  • The Tile.updatePixelXY method now updates the tile XY position based on map type.
  • ParseTilesets will now correctly handle non-consecutive tile IDs. It also now correctly sets the maxId property, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)
  • Tilemap.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • LayerData.orientation is a new property that holds the tilemap layers orientation constant.
  • LayerData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • MapData.orientation is a new property that holds the tilemap layers orientation constant.
  • MapData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • Tilemaps.Components.HexagonalWorldToTileY is a new function that converts a world Y coordinate to hexagonal tile Y coordinate.
  • Tilemaps.Components.StaggeredWorldToTileY is a new function that converts a world Y coordinate to staggered tile Y coordinate.
  • Tilemaps.Components.HexagonalWorldToTileXY is a new function that converts world coordinates to hexagonal tile coordinates.
  • Tilemaps.Components.IsometricWorldToTileXY is a new function that converts world coordinates to isometric tile coordinates.
  • Tilemaps.Components.StaggeredWorldToTileXY is a new function that converts world coordinates to staggered tile coordinates.
  • Tilemaps.Components.HexagonalTileToWorldY is a new function that converts a hexagonal Y coordinate to a world coordinate.
  • Tilemaps.Components.StaggeredTileToWorldY is a new function that converts a staggered Y coordinate to a world coordinate.
  • Tilemaps.Components.HexagonalTileToWorldXY is a new function that converts hexagonal tile coordinates to world coordinates.
  • Tilemaps.Components.IsometricTileToWorldXY is a new function that converts isometric tile coordinates to world coordinates.
  • Tilemaps.Components.StaggeredTileToWorldXY is a new function that converts staggered tile coordinates to world coordinates.
  • Tilemaps.Components.GetTileToWorldXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldXXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetCullTilesFunction is a new function that returns the correct culling function to use.
  • Tilemaps.Components.HexagonalCullTiles is a new function that culls tiles in a hexagonal map.
  • Tilemaps.Components.StaggeredCullTiles is a new function that culls tiles in a staggered map.
  • Tilemaps.Components.IsometricCullTiles is a new function that culls tiles in a isometric map.
  • Tilemaps.Components.CullBounds is a new function that calculates the cull bounds for an orthogonal map.
  • Tilemaps.Components.HexagonalCullBounds is a new function that calculates the cull bounds for a hexagonal map.
  • Tilemaps.Components.StaggeredCullBounds is a new function that calculates the cull bounds for a staggered map.
  • Tilemaps.Components.RunCull is a new function that runs the culling process from the combined bounds and tilemap.
  • Tilemap._convert is a new internal private hash of tilemap conversion functions used by the public API.
  • The Tilemap._isStaticCall method has been removed and no Tilemap methods now check this, leading to faster execution.

Mesh Game Object - New Features, Updates and API Changes

The Mesh Game Object has been rewritten from scratch in v3.50 with a lot of changes to make it much more useful. It is accompanied by the new Geom.Mesh set of functions.

  • Geom.Mesh is a new namespace that contains the Mesh related geometry functions. These are stand-alone functions that you may, or may not require, depending on your game.
  • Geom.Mesh.Vertex is a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.
  • Geom.Mesh.Face is a new class that consists of references to the three Vertex instances that construct a single Face in a Mesh and provides methods for manipulating them.
  • Geom.Mesh.GenerateVerts is a new function that will return an array of Vertex and Face objects generated from the given data. You can provide index, or non-index vertex lists, along with UV data, normals, colors and alpha which it will parse and return the results from.
  • Geom.Mesh.GenerateGridVerts is a new function that will generate a series of Vertex objects in a grid format, based on the given GenerateGridConfig config file. You can set the size of the grid, the number of segments to split it into, translate it, color it and tile the texture across it. The resulting data can be easily used by a Mesh Game Object.
  • Geom.Mesh.GenerateObjVerts is a new function that will generate a series of Vertex objects based on the given parsed Wavefront Obj Model data. You can optionally scale and translate the generated vertices and add them to a Mesh.
  • Geom.Mesh.ParseObj is a new function that will parse a triangulated Wavefront OBJ file into model data into a format that the GenerateObjVerts function can consume.
  • Geom.Mesh.ParseObjMaterial is a new function that will parse a Wavefront material file and extract the diffuse color data from it, combining it with the parsed object data.
  • Geom.Mesh.RotateFace is a new function that will rotate a Face by a given amount, based on an optional center of rotation.
  • Loader.OBJFile is a new File Loader type that can load triangulated Wavefront OBJ files, and optionally material files, which are then parsed and stored in the OBJ Cache.
  • The Mesh constructor and MeshFactory signatures have changed to scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first. indicies is a new parameter that allows you to provide indexed vertex data to create the Mesh from, where the indicies array holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. The indicies array is optional. If your data is not indexed, then simply pass null or an empty array for this parameter.
  • The Mesh Game Object now has the Animation State Component. This allows you to create and play animations across the texture of a Mesh, something that previously wasn't possible. As a result, the Mesh now adds itself to the Update List when added to a Scene.
  • Mesh.addVertices is a new method that allows you to add vertices to a Mesh Game Object based on the given parameters. This allows you to modify a mesh post-creation, or populate it with data at a later stage.
  • Mesh.addVerticesFromObj is a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the new OBJFile with a this.load.obj call, then you can use the key with this method. This method also takes an optional scale and position parameters to control placement of the created model within the Mesh.
  • Mesh.hideCCW is a new boolean property that, when enabled, tells a Face to not render if it isn't counter-clockwise. You can use this to hide backward facing Faces.
  • Mesh.modelPosition is a new Vector3 property that allows you to translate the position of all vertices in the Mesh.
  • Mesh.modelRotation is a new Vector3 property that allows you to rotate all vertices in the Mesh.
  • Mesh.modelScale is a new Vector3 property that allows you to scale all vertices in the Mesh.
  • Mesh.panX is a new function that will translate the view position of the Mesh on the x axis.
  • Mesh.panY is a new function that will translate the view position of the Mesh on the y axis.
  • Mesh.panZ is a new function that will translate the view position of the Mesh on the z axis.
  • Mesh.updateProjectionMatrix is a new method that allows you to set the projection matrix based on the given size, fov, near and far values.
  • Mesh.clear is a new method that will destroy all Faces and Vertices and clear the Mesh.
  • Mesh.depthSort is a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.
  • Mesh.addVertex is a new method that allows you to add a new single Vertex into the Mesh.
  • Mesh.addFace is a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.
  • Mesh.getFaceCount new is a new method that will return the total number of Faces in the Mesh.
  • Mesh.getVertexCount new is a new method that will return the total number of Vertices in the Mesh.
  • Mesh.getFace new is a new method that will return a Face instance from the Mesh based on the given index.
  • Mesh.getFaceAt new is a new method that will return an array of Face instances from the Mesh based on the given position. The position is checked against each Face, translated through the optional Camera and Mesh matrix. If more than one Face intersects, they will all be returned but the array will be depth sorted first, so the first element will be that closest to the camera.
  • Mesh.vertices is now an array of GameObject.Vertex instances, not a Float32Array.
  • Mesh.faces is a new array of GameObject.Face instances, which is populated during a call to methods like addVertices or addModel.
  • Mesh.totalRendered is a new property that holds the total number of Faces that were rendered in the previous frame.
  • Mesh.setDebug is a new method that allows you to render a debug visualisation of the Mesh vertices to a Graphics Game Object. You can provide your own Graphics instance and optionally callback that is invoked during rendering. This allows you to easily visualise the vertices of your Mesh to help debug UV mapping.
  • The Mesh now renders by iterating through the Faces array, not the vertices. This allows you to use Array methods such as BringToTop to reposition a Face, thus changing the drawing order without having to repopulate all of the vertices. Or, for a 3D model, you can now depth sort the Faces.
  • The Mesh Game Object now extends the SingleAlpha component and the alpha value is factored into the final alpha value per vertex during rendering. This means you can now set the whole alpha across the Mesh using the standard setAlpha methods. But, if you wish to, you can still control the alpha on a per-vertex basis as well.
  • The Mesh renderer will now check to see if the pipeline capacity has been exceeded for every Face added, allowing you to use Meshes with vertex counts that exceed the pipeline capacity without causing runtime errors.
  • You can now supply just a single numerical value as the colors parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the color for all vertices created.
  • You can now supply just a single numerical value as the alphas parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the alpha for all vertices created.
  • Mesh.debugGraphic is a new property that holds the debug Graphics instance reference.
  • Mesh.debugCallback is a new property that holds the debug render callback.
  • Mesh.renderDebugVerts is a new method that acts as the default render callback for setDebug if none is provided.
  • Mesh.preDestroy is a new method that will clean-up the Mesh arrays and debug references on destruction.
  • Mesh.isDirty is a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically in preUpdate to avoid generating lots of math when nothing has changed.
  • The Mesh.uv array has been removed. All UV data is now bound in the Vertex instances.
  • The Mesh.colors array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.alphas array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.tintFill property is now a boolean and defaults to false.

Quad Game Object Removed

The Quad Game Object has been removed from v3.50.0.

You can now create your own Quads easily using the new Geom.Mesh.GenerateGridVerts function, which is far more flexible than the old quads were.

Input / Mouse Updates and API Changes

  • ScaleManager.refresh is now called when the Game.READY event fires. This fixes a bug where the Scale Manager would have the incorrect canvas bounds, because they were calculated before a previous canvas was removed from the DOM. Fix #4862 (thanks @dranitski)
  • The Game Config property inputMouseCapture has been removed, as this is now split into 3 new config options:
  • inputMousePreventDefaultDown is a new config option that allows you to control preventDefault calls specifically on mouse down events. Set it via input.mouse.preventDefaultDown in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultUp is a new config option that allows you to control preventDefault calls specifically on mouse up events. Set it via input.mouse.preventDefaultUp in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultMove is a new config option that allows you to control preventDefault calls specifically on mouse move events. Set it via input.mouse.preventDefaultMove in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultWheel is a new config option that allows you to control preventDefault calls specifically on mouse wheel events. Set it via input.mouse.preventDefaultWheel in the Game Config. It defaults to true, the same as the previous capture property did.
  • The MouseManager.capture property has been removed, as this is now split into 3 new config options (see below)
  • MouseManager.preventDefaultDown is a new boolean property, set via the inputMousePreventDefaultDown config option that allows you to toggle capture of mouse down events at runtime.
  • MouseManager.preventDefaultUp is a new boolean property, set via the inputMousePreventDefaultUp config option that allows you to toggle capture of mouse up events at runtime.
  • MouseManager.preventDefaultMove is a new boolean property, set via the inputMousePreventDefaultMove config option that allows you to toggle capture of mouse move events at runtime.
  • MouseManager.preventDefaultWheel is a new boolean property, set via the inputMousePreventDefaultWheel config option that allows you to toggle capture of mouse wheel at runtime.
  • In the MouseManager the up, down and move events are no longer set as being passive if captured. Over, Out, Wheel and the Window level Down and Up events are always flagged as being passive. Wheel events are non-passive if capturing is enabled.
  • The GamepadPlugin will now call refreshPads as part of its start process. This allows you to use Gamepads across multiple Scenes, without having to wait for a connected event from each one of them. If you've already had a connected event in a previous Scene, you can now just read the pads directly via this.input.gamepad.pad1 and similar. Fix #4890 (thanks @Sytten)
  • Shutting down the Gamepad plugin (such as when sleeping a Scene) no longer calls GamepadPlugin.disconnectAll, but destroying it does.
  • Gamepad._created is a new private internal property that keeps track of when the instance was created. This is compared to the navigator timestamp in the update loop to avoid event spamming. Fix #4890.
  • Pointer.down will now check if the browser is running under macOS and if the ctrl key was also pressed, if so, it will flag the down event as being a right-click instead of a left-click, as per macOS conventions. Fix #4245 (thanks @BigZaphod)
  • When destroying an interactive Game Object that had useHandCursor enabled, it would reset the CSS cursor to default, even if the cursor wasn't over that Game Object. It will now only reset the cursor if it's over the Game Object being destroyed. Fix #5321 (thanks @JstnPwll)
  • The InputPlugin.shutdown method will now reset the CSS cursor, in case it was set by any Game Objects in the Scene that have since been destroyed.
  • The InputPlugin.processOverEvents has had a duplicate internal loop removed from it (thanks KingCosmic)

Tint Updates and Shader Changes

Phaser has had the ability to apply an additive tint to a Game Object since the beginning, and gained 'filled tints', with and without texture alpha, in v3.11. While this was handy, it introduced a 3-way if-else condition to the shaders to handle the different modes. Plus, setting tint colors was also generating rgb order Float32 color values for each Game Object, making reading those colors back again difficult (as they'd return in BGR order).

This has all changed in 3.50, as outlined below. Tint values are now used directly in the shader and don't pass through a color conversion function first. Lots of private properties have been removed and the shaders no longer have a 3-way if-else block. All of this means improved performance and a slight reduction in memory overhead.

  • Tint.tintTopLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTL which has now been removed.
  • Tint.tintTopRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTR which has now been removed.
  • Tint.tintBottomLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBL which has now been removed.
  • Tint.tintBottomRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBR which has now been removed.
  • The property Tint._isTinted has been removed as it's no longer required.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they now read the color value as outTint.bgr instead of outTint.rgb. This allows the colors to remain in RGB order within the Tint component.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they no longer have a 3-way check on the outTintEffect value.
  • The Multi Pipeline, Bitmap Text, Render Texture, Text, TileSprite and Camera now all read the tint values from the public properties instead of the private _tintTL etc ones. They also now set the tintEffect value directly from the tintFill property, removing another conditional check.
  • The function GetColorFromValue has been removed as it's no longer used internally.
  • The Rope.tintFill property is now a boolean, not an integer, and can no longer take 2 as a value for a complete fill. Instead, you should provide a solid color texture with no alpha.
  • As a result of the change to the shader, all uses of the WebGL Util function getTintAppendFloatAlphaAndSwap have been replaced with getTintAppendFloatAlpha instead.
  • As a result of the change to the shader, the Multi Pipeline now uses the WebGLRenderer.whiteTexture and tintEffect mode of 1 by default, instead of mode 2 (which has been removed) and a transparent texture. This ensures Graphics and Shapes objects still render correctly under the new smaller shader code.
  • WebGLRenderer.whiteTexture is a new property that is a reference to a pure white 4x4 texture that is created during Boot by the Texture Manager. The Multi Pipeline uses this internally for all Graphic, Shape and fill rendering.
  • The TextureManager now generates a new texture with the key __WHITE durings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines.
  • Config.images.white is a new Game Config property that specifies the 4x4 white PNG texture used by Graphics rendering. You can override this via the config, but only do so if needed.

Arcade Physics Updates

Prior to v3.50 an Arcade Physics Body could be one of two states: immovable, or moveable. An immovable body could not receive any impact from another Body. If something collided with it, it wouldn't even separate to break free from the collision (the other body had to take the full separation value). It was intended for objects such as platforms, ground or walls, there they absolutely shouldn't move under any circumstances. As a result, two immovable bodies could never be collided together. While this worked for scenery-like items, it didn't work if you required maybe 2 players who could collide with each other, but should never be able to push one another. As of 3.50 all physics bodies now have a new property pushable that allows this. A pushable body can share separation with its collider, as well as take on mass-based velocity from the impact. A non-pushable body will behave differently depending on what it collides with. For example, a pushable body hitting a non-pushable (or immoveable) body will rebound off it.

  • The Arcade Physics Body class has a new boolean property pushable (true, by default). This allows you to set if a Body can be physically pushed by another Body, or not. Fix #4175 #4415 (thanks @inmylo @CipSoft-Components)
  • Body.setPushable is a new chainable method that allows you to set the pushable state of a Body.
  • Arcade.Components.Pushable is a new component, inherited by the standard Arcade Physics Image and Sprite classes.
  • Bodies will now check to see if they are blocked in the direction they're being pushed, before resolving the collision. This helps stop some bodies from being pushed into other objects.
  • Bodies will now check which direction they were moving and separate accordingly. This helps stop some bodies from being pushed into other objects.
  • ArcadePhysics.disableUpdate is a new method that will prevent the Arcade Physics World update method from being called when the Scene updates. By disabling it, you're free to call the update method yourself, passing in your own delta and time values.
  • ArcadePhysics.enableUpdate is a new method that will make the Arcade Physics World update in time with the Scene update. This is the default, so only call this if you have specifically disabled it previously.
  • ArcadeWorldConfig.customUpdate is a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. If true the World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)
  • Physics.Arcade.Body.setCollideWorldBounds now has a new optional parameter onWorldBounds which allows you to enable the Body's onWorldBounds property in the same call (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityX is a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityY is a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)
  • The PhysicsGroup config now has two new optional properties maxVelocityX and maxVelocityY which allows you to set the maximum velocity on bodies added to the Group (thanks @samme)
  • The Arcade.Body.resetFlags method has a new optional boolean parameter clear. If set, it clears the wasTouching flags on the Body. This happens automatically when Body.reset is called. Previous to this, the flags were not reset until the next physics step (thanks @samme)
  • Physics.Arcade.ProcessX is a new set of functions, called by the SeparateX function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Physics.Arcade.ProcessY is a new set of functions, called by the SeparateY function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Arcade.Body.center values were incorrect after collisions with the world bounds or (for rectangular bodies) after collisions with another body. The body center is now updated after those separations (thanks @samme)

Loader Cache Changes

When loading any of the file types listed below it will no longer store the data file in the cache. For example, when loading a Texture Atlas using a JSON File, it used to store the parsed image data in the Texture Manager and also store the JSON in the JSON Cache under the same key. This has changed in 3.50. The data files are no longer cached, as they are not required by the textures once parsing is completed, which happens during load. This helps free-up memory. How much depends on the size of your data files. And also allows you to easily remove textures based on just their key, without also having to clear out the corresponding data cache.

  • AtlasJSONFile no longer stores the JSON in the JSON Cache once the texture has been created.
  • AtlasXMLFile no longer stores the XML in the XML Cache once the texture has been created.
  • UnityAtlasFile no longer stores the Text in the Text Cache once the texture has been created.
  • BitmapFontFile no longer stores the XML in the XML Cache once the texture has been created.
  • You can now use TextureManager.remove to remove a texture and not have to worry about clearing the corresponding JSON or XML cache entry as well in order to reload a new texture using the same key. Fix #5323 (thanks @TedGriggs)

Removal of 'resolution' property from across the API

For legacy reasons, Phaser 3 has never properly supported HighDPI devices. It will render happily to them of course, but wouldn't let you set a 'resolution' for the Canvas beyond 1. Earlier versions of 3.x had a resolution property in the Game Config, but it was never fully implemented (for example, it would break zooming cameras). When the Scale Manager was introduced in v3.16 we forced the resolution to be 1 to avoid it breaking anything else internally.

For a long time, the 'resolution' property has been present - taunting developers and confusing new comers. In this release we have finally gone through and removed all references to it. The Game Config option is now gone, it's removed from the Scale Manager, Base Camera and everywhere else where it matters. As much as we would have liked to implement the feature, we've spent too long without it, and things have been built around the assumption it isn't present. The API just wouldn't cope with having it shoe-horned in at this stage. As frustrating as this is, it's even more annoying to just leave the property there confusing people and wasting CPU cycles. Phaser 4 has been built with HighDPI screens in mind from the very start, but it's too late for v3. The following changes are a result of this removal:

  • The Phaser.Scale.Events#RESIZE event no longer sends the resolution as a parameter.
  • The BaseCamera.resolution property has been removed.
  • The internal private BaseCamera._cx, _cy, _cw and _ch properties has been removed, use x, y, width and height instead.
  • The BaseCamera.preRender method no longer receives or uses the resolution parameter.
  • The Camera.preRender method no longer receives or uses the resolution parameter.
  • The CameraManager.onResize method no longer receives or uses the resolution parameter.
  • The Core.Config.resolution property has been removed.
  • The TextStyle.resolution property is no longer read from the Game Config. You can still set it via the Text Style config to a value other than 1, but it will default to this now.
  • The CanvasRenderer no longer reads or uses the Game Config resolution property.
  • The PipelineManager.resize method along with WebGLPipeline.resize and anything else that extends them no longer receives or uses the resolution parameter.
  • The WebGLRenderer.resize and onResize methods no longer receives or uses the resolution parameter.
  • The ScaleManager.resolution property has been removed and all internal use of it.

Removed 'interpolationPercentage' parameter from all render functions

Since v3.0.0 the Game Object render functions have received a parameter called interpolationPercentage that was never used. The renderers do not calculate this value and no Game Objects apply it, so for the sake of clairty, reducing code and removing complexity from the API it has been removed from every single function that either sent or expected the parameter. This touches every single Game Object and changes the parameter order as a result, so please be aware of this if you have your own custom Game Objects, or plugins, that implement their own render methods. In terms of surface API changes, you shouldn't notice anything at all from this removal.

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • WebGLRenderer.setInt1iv will allow you to look-up and set a 1iv uniform on the given shader.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.
  • You can now use this.renderer from within a Scene, as it's now a Scene-level property and part of the Injection Map.
  • Clock.addEvent can now take an existing TimerEvent object, as well as a config object. If a TimerEvent is given it will be removed from the Clock, reset and then added. This allows you to pool TimerEvents rather than constantly create and delete them. Fix #4115 (thanks @jcyuan)
  • Clock.removeEvent is a new method that allows you to remove a TimerEvent, or an array of them, from all internal lists of the current Clock.
  • Group.getMatching is a new method that will return any members of the Group that match the given criteria, such as getMatching('visible', true) (thanks @atursams)
  • Utils.Array.SortByDigits is a new function that takes the given array of strings and runs a numeric sort on it, ignoring any non-digits.
  • GroupCreateConfig, which is used when calling Group.createMultiple or Group.createFromConfig, can now accept the following new properties: setOrigin: { x, y, stepX, stepY } which are applied to the items created by the Group.
  • Transform.copyPosition is a new method that will copy the position from the given object to the Game Object (thanks @samme)
  • The Text.MeasureText function, which is used to calculate the ascent and descent of Text Game Objects whenever the style, or font size, is changed, has been updated to use the new actualBoundingBoxAscent functions present in modern browsers. This allows for significantly faster ascent calculations than previously. Older browsers, such as IE, will still fall back (thanks @rexrainbow)
  • GameObjects.GetCalcMatrix is a new function that is used to calculate the transformed Game Object matrix, based on the given Game Object, Camera and Parent. This function is now used by the following Game Objects: BitmapText (Static and Dynamic), Graphics, Extern, Mesh, Rope, Shader, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. This dramatically reduces the amount of duplicate code across the API.
  • Utils.Array.Matrix.Translate is a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.
  • Vertor3.addScale is a new method that will add the given vector and multiply it in the process.
  • When defining the ease used with a Particle Emitter you can now set easeParams in the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh)
  • BitmapMask.createMask is a new method that will internally create the WebGL textures and framebuffers required for the mask. This is now used by the constructor and if the context is lost. It now also clears any previous textures/fbos that may have been created first, helping prevent memory leaks.
  • BitmapMask.clearMask will delete any WebGL textures or framebuffers the mask is using. This is now called when the mask is destroyed, or a new mask is created upon it.
  • Quaternion now has a new property onChangeCallback which, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.
  • The Quaternion.set method has a new optional boolean parameter update (defaults to true), which will call the onChangeCallback if set.
  • Quaternion.setFromEuler is a new method that will set the quaternion from the given Euler object, optionally calling the onChangeCallback in the process.
  • Quaternion.setFromRotationMatrix is a new method that will set the rotation of the quaternion from the given Matrix4.
  • Vector3.setFromMatrixPosition is a new method that will set the components of the Vector3 based on the position of the given Matrix4.
  • Vector3.setFromMatrixColumn is a new method that will set the components of the Vector3 based on the specified Matrix4 column.
  • Vector3.fromArray is a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.
  • Vector3.min is a new method that will set the components of the Vector3 based on the Main.min between it and the given Vector3.
  • Vector3.max is a new method that will set the components of the Vector3 based on the Main.max between it and the given Vector3.
  • Vector3.addVectors is a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.
  • Vector3.addScalar is a new method that will multiply the components of the Vector3 by the scale value given.
  • Vector3.applyMatrix3 is a new method that will take a Matrix3 and apply it to the Vector3.
  • Vector3.applyMatrix4 is a new method that will take a Matrix4 and apply it to the Vector3.
  • Vector3.projectViewMatrix is a new method that multiplies the Vector3 by the given view and projection matrices.
  • Vector3.unprojectViewMatrix is a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.
  • Matrix4.setValues is a new method that allows you to set all of the matrix components individually. Most internal methods now use this.
  • Matrix.multiplyToMat4 is a new method that multiplies a Matrix4 by the given src Matrix4 and stores the results in the out Matrix4.
  • Matrix4.fromRotationXYTranslation is a new method that takes the rotation and position vectors and builds this Matrix4 from them.
  • Matrix4.getMaxScaleOnAxis is a new method that will return the maximum axis scale from the Matrix4.
  • Matrix4.lookAtRH is a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.
  • Matrix4.transform is a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.
  • Matrix4.multiplyMatrices is a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.
  • Matrix4.premultiply is a new method that takes a Matrix4 and multiplies it by the current Matrix4.
  • Matrix4.getInverse is a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.
  • WebGLRenderer.instancedArraysExtension is a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.
  • WebGLRenderer.vaoExtension is a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Earcut has now been exposed and is available via Geom.Polygon.Earcut and is fully documented.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.
  • Pointer.downTime now stores the event timestamp of when the first button on the input device was pressed down, not just when button 1 was pressed down.
  • Pointer.upTime now stores the event timestamp of when the final depressed button on the input device was released, not just when button 1 was released.
  • The Pointer.getDuration method now uses the new Pointer downTime and upTime values, meaning it will accurately report the duration of when any button is being held down, not just the primary one. Fix #5112 (thanks @veleek)
  • The BaseShader default vertex shader now includes the outTexCoord vec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok)
  • When using the GameObjectCreator for Containers you can now specify the children property in the configuration object.
  • WebGLRenderer.finalType is a new boolean property that signifies if the current Game Object being rendered is the final one in the list.
  • The WebGLRenderer.updateCanvasTexture method will now set gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL to true, which should stop issues where you update a Text Game Object, having added a Render Texture or Spine Game Object to the Scene after it, which switches the PMA setting. Fix #5064 #5155 (thanks @hugoruscitti @immangrove-supertree)
  • Textures.Parsers.JSONHash will now perform a hasOwnProperty check when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes from JSON.parse. Fix #4768 (thanks @RollinSafary)
  • The Camera3D Plugin has been rebuilt for Phaser 3.50 and the webpack config updated. This plugin is now considered deprecated and will not be updated beyond this release.
  • Tween.seek will no longer issue a console warning for 'Tween.seek duration too long', it's now up to you to check on the performance of tween seeking.
  • WebGLRenderer.previousPipeline is a new property that is set during a call to clearPipeline and used during calls to rebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.
  • The WebGLRenderer.rebindPipeline method has been changed slightly. Previously, you had to specify the pipelineInstance, but this is now optional. If you don't, it will use the new previousPipeline property instead. If not set, or none given, it will now return without throwing gl errors as well.
  • If inputWindowEvents is set in the Game Config, then the MouseManager will now listen for the events on window.top instead of just window, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in a try/catch block, as not all sites allow access to window.top (specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow)
  • MouseManager.isTop is a new boolean read-only property that flags if the mouse event listeners were attached to window.top (true), or just window (false). By default Phaser will attempt window.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back to window in those cases and set this property to false (thanks BunBunBun)
  • Types.GameObjects.Text.GetTextSizeObject is a new type def for the GetTextSize function results.
  • Utils.Array.StableSort has been recoded. It's now based on Two-Screens stable sort 0.1.8 and has been updated to fit into Phaser better and no longer create any window bound objects. The inplace function has been removed, just call StableSort(array) directly now. All classes that used StableSort.inplace have been updated to call it directly.
  • If a Scene is paused, or sent to sleep, it will automatically call Keyboard.resetKeys. This means that if you hold a key down, then sleep or pause a Scene, then release the key and resume or wake the Scene, it will no longer think it is still being held down (thanks @samme)
  • Actions.setOrigin will now call updateDisplayOrigin on the items array, otherwise the effects can't be seen when rendering.
  • You can now set the ArcadeWorld.fixedStep property via the ArcadeWorldConfig object (thanks @samme)
  • Utils.Array.NumerArray can now accept the start and end parameters in reverse order, i.e. 10, 1 will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.
  • DataManager.Events.DESTROY is a new event that the Data Manager will listen for from its parent and then call its own destroy method when received.
  • The Quaternion class constructor will now default the values to 0,0,0,1 if they're not provided, making it an identity quaternion, rather than the 0,0,0,0 it was before.
  • You can now set the ParticleEmitter.reserve value via the emitter configuration object (thanks @vforsh)
  • Setting the pixelArt config option will now set antialiasGL to false, as well as antialias. Fix #5309 (thanks @Vegita2)
  • The Shape class now includes the ComputedSize component properties and methods directly in the class, rather than applying as a mixin. setSize is now flagged as being private, because it shouldn't be used on Shape classes, which was leading to confusion as it appeared in the public-facing API. Fix #4811 (thanks @aolsx)
  • The Loader.maxParallelDownloads value is now set to 6 if running on Android, or 32 on any other OS. This avoids net::ERR_FAILED issues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary)
  • WebGLRenderer.defaultScissor is a new property that holds the default scissor dimensions for the renderer. This is modified during resize and avoids continuous array generation in the preRender loop.
  • When running an Arcade Physics overlap test against a StaticBody, it will no longer set the blocked states of the dynamic body. If you are doing a collision test, they will still be set, but they're skipped for overlap-only tests. Fix #4435 (thanks @samme)
  • The Line Game Object will now default its width and height to 1, rather than zero. This allows you to give Line objects a physics body (although you will still need to re-adjust the center of the body manually). Fix #4596 (thanks @andrewaustin)
  • Internally, the Quaternion class now has 4 new private properties: _x, _y, _z and _w and 4 new getters and setters for the public versions. It also now passes most methods via set to allow for the onChange callback to be invoked. This does not change the public-facing API.
  • Group now extends EventEmitter, allowing you to emit custom events from within a Group.
  • Device.Audio.wav now uses audio/wav as the canPlayType check string, instead of audio/wav; codecs="1", which should allow iOS13 to play wav files again.
  • In the Loader.FileTypes.TextFile config you can now override the type and cache destination for the file.
  • Loader.MultiFile will now parse the given files array and only add valid entries into the file list, allowing multifiles to now have optional file entries.

Bug Fixes

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)
  • The GridAlign action didn't work if only the height parameter was set. Fix #5019 (thanks @halilcakar)
  • The Color.HSVToRGB function has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX)
  • Previously, the easeParams array within a Tweens props object, or a multi-object tween, were ignored and it was only used if set on the root Tween object. It will now work correctly set at any depth. Fix #4292 (thanks @willblackmore)
  • When using Camera.setRenderToTexture its zoom and rotation values would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok)
  • GameObjects.Shape.Grid would render a white fill even if you passed undefined as the fill color in the constructor. It now doesn't render cells if no fill color is given.
  • The onMouse events in the Input Manager didn't reset the activePointer property to the mouse, meaning on dual-input systems such as Touch Screen devices, the active pointer would become locked to whichever input method was used first. Fix #4615 #5232 (thanks @mmolina01 @JstnPwll @Legomite)
  • The Scale Managers GetScreenOrientation function will now check for window.orientation first, because iOS mobile browsers have an incomplete implementation of the Screen API, forcing us to use the window value as a priority. This means the Scale Manager will now emit orientationchange events correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu)
  • Time.Clock.addEvent can now take an instance of a TimerEvent as its parameter. Fix #5294 (thanks @samme @EmilSV)
  • GameConfig.audio now defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)
  • The Loader.path was being added to the File URL even if the URL was absolute. This is now checked for and the path is not applied unless the URL is relative (thanks @firesoft)
  • Group.getMatching would always return an empty array. It now returns matching children (thanks @samme)
  • The ParticleManagerWebGLRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in follow offsets separately. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers. Fix #5319 #5195 #4739 #4691 (thanks @vforsh @condeagustin @IvanDem @Formic)
  • The ParticleManagerCanvasRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also uses setToContext internally. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers, or having the Camera zoomed, running under Canvas. Fix #4908 #4531 #4131 (thanks @smjnab @SirLink @jhooper04)
  • The Graphics WebGL Renderer will now default to pathOpen = true. This fixes issues under WebGL where, for example, adding an arc and calling strokePath, without first calling beginPath will no longer cause rendering artefacts when WebGL tries to close the path with a single tri.
  • Graphics.strokeRoundedRect now issues moveTo commands as part of the drawing sequence, preventing issues under WebGL where on older Android devices it would project additional vertices into the display. Fix #3955 (thanks @alexeymolchan)
  • Creating a Bitmap Mask from a texture atlas that was then used to mask another Game Object also using that same texture atlas would throw the error GL_INVALID_OPERATION : glDrawArrays: Source and destination textures of the draw are the same.. It now renders as expected. Fix #4675 (thanks @JacobCaron)
  • When using the same asset for a Game Object to be used as a mask, it would make other Game Objects using the same asset, that appeared above the mask in the display list, to not render. Fix #4767 (thanks @smjnab)
  • When taking a snapshot in WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in the WebGLSnapshot function. Fix #4956 (thanks @gammafp @telinc1)
  • You can now draw a Group to a RenderTexture. Previously, it failed to pass the camera across, resulting in none of the Group children being drawn. Fix #5330 (thanks @somnolik)

Namespace Updates

  • The Phaser.Curves.MoveTo function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.DOM.GetInnerHeight function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Bob class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsManager class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsPlugin class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Particles.EmitterOp class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.GetTextSize function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.MeasureText function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.TextStyle function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Input.CreatePixelPerfectHandler function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapCirc function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapRect function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Tilemap namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Components namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.MatterGameObject class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.PointerConstraint class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetPhysicsPlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetScenePlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Structs.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Tilemaps.Parsers.Tiled function has now been exposed on the Phaser namespace (thanks @samme)
  • Every single Tilemap.Component function has now been made public. This means you can call the Component functions directly, should you need to, outside of the Tilemap system.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360 @volkans80 @jaabberwocky @maikthomas @atursams @LearningCode2023 @DylanC @BenjaminDRichards @rexrainbow @Riderrr @spwilson2 @EmilSV @PhaserEditor2D @Gangryong @vinerz

- JavaScript
Published by photonstorm over 5 years ago

phaser - Phaser v3.50.0 Beta 8

Version 3.50.0 - Subaru - in development

WebGL Pipeline Updates

If you use a custom WebGL Pipeline in your game, you must update your code in order to use Phaser 3.50.

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

Other pipeline changes are as follows:

  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.
  • The WebGLPipeline.shouldFlush method now accepts an optional parameter amount. If given, it will return true if when the amount is added to the vertex count it will exceed the vertex capacity. The Multi Pipeline has been updated to now use this method instead of performing the comparison multiple times itself.
  • The RopePipeline now extends MultiPipeline and just changes the topolgy, vastly reducing the filesize.

Pipeline Uniform Changes

Piplines now have a new uniforms array that can be passed in with the config. All default pipelines now set these. The array contains the names, as strings, of all uniforms your pipeline shader uses. Once the pipeline shader has been successfully linked, it will use the array of names to look-up the WebGLUniformLocation of all uniforms specified. These are stored in the new WebGLPipeline.uniforms object. This takes place in the new WebGLPipeline.setUniformLocations method.

When a pipeline is bound, you can now use the new methods (listed below) to set uniform values directly on the pipeline. Previously, calling a method such as setFloat3 on a pipeline would pass that call over to WebGLRenderer. The renderer would first check to see if the pipeline program was current, and if not, make it so, before then looking up the uniform location and finally setting it. This is a lot of steps to take for pipelines that potentially need to change uniforms for every Game Object they render.

Under the new methods, and using the new pre-cached uniform locations, these extra steps are skipped. The uniform value is set directly, no shader binding takes place and no location look-up happens. This dramatically reduces the number of WebGL ops being issued per frame. To clearly differentiate these pipline methods, we have renamed them. The new method names are as follows:

  • WebGLPipeline.set1f will set a 1f uniform based on the given name.
  • WebGLPipeline.set2f will set a 2f uniform based on the given name.
  • WebGLPipeline.set3f will set a 3f uniform based on the given name.
  • WebGLPipeline.set4f will set a 4f uniform based on the given name.
  • WebGLPipeline.set1fv will set a 1fv uniform based on the given name.
  • WebGLPipeline.set2fv will set a 2fv uniform based on the given name.
  • WebGLPipeline.set3fv will set a 3fv uniform based on the given name.
  • WebGLPipeline.set4fv will set a 4fv uniform based on the given name.
  • WebGLPipeline.set1iv will set a 1iv uniform based on the given name.
  • WebGLPipeline.set2iv will set a 2iv uniform based on the given name.
  • WebGLPipeline.set3iv will set a 3iv uniform based on the given name.
  • WebGLPipeline.set4iv will set a 4iv uniform based on the given name.
  • WebGLPipeline.set1i will set a 1i uniform based on the given name.
  • WebGLPipeline.set2i will set a 2i uniform based on the given name.
  • WebGLPipeline.set3i will set a 3i uniform based on the given name.
  • WebGLPipeline.set4i will set a 4i uniform based on the given name.
  • WebGLPipeline.setMatrix2fv will set a matrix 2fv uniform based on the given name.
  • WebGLPipeline.setMatrix3fv will set a matrix 3fv uniform based on the given name.
  • WebGLPipeline.setMatrix4fv will set a matrix 4fv uniform based on the given name.

If your code uses any of the old method names, please update them using the list below:

  • WebGLPipeline.setFloat1 has been removed. Please use set1f instead.
  • WebGLPipeline.setFloat2 has been removed. Please use set2f instead.
  • WebGLPipeline.setFloat3 has been removed. Please use set3f instead.
  • WebGLPipeline.setFloat4 has been removed. Please use set4f instead.
  • WebGLPipeline.setFloat1v has been removed. Please use set1fv instead.
  • WebGLPipeline.setFloat2v has been removed. Please use set2fv instead.
  • WebGLPipeline.setFloat3v has been removed. Please use set3fv instead.
  • WebGLPipeline.setFloat4v has been removed. Please use set4fv instead.
  • WebGLPipeline.setInt1 has been removed. Please use set1i instead.
  • WebGLPipeline.setInt2 has been removed. Please use set2i instead.
  • WebGLPipeline.setInt3 has been removed. Please use set3i instead.
  • WebGLPipeline.setInt4 has been removed. Please use set4i instead.
  • WebGLPipeline.setMatrix1 has been removed. Please use setMatrix2fv instead.
  • WebGLPipeline.setMatrix2 has been removed. Please use setMatrix3fv instead.
  • WebGLPipeline.setMatrix3 has been removed. Please use setMatrix4fv instead.

Pipeline Manager

The WebGL.PipelineManager is a new class that is responsbile for managing all of the WebGL Pipelines in Phaser. An instance of the Pipeline Manager is created by the WebGL Renderer and is available under the pipelines property. This means that the WebGL Renderer no longer handles pipelines directly, causing the following API changes:

  • WebGLRenderer.pipelines is no longer a plain object containing pipeline instances. It's now an instance of the PipelineManager class. This instance is created during the init and boot phase of the renderer.
  • The WebGLRenderer.currentPipeline property no longer exists, instead use PipelineManager.current.
  • The WebGLRenderer.previousPipeline property no longer exists, instead use PipelineManager.previous.
  • The WebGLRenderer.hasPipeline method no longer exists, instead use PipelineManager.has.
  • The WebGLRenderer.getPipeline method no longer exists, instead use PipelineManager.get.
  • The WebGLRenderer.removePipeline method no longer exists, instead use PipelineManager.remove.
  • The WebGLRenderer.addPipeline method no longer exists, instead use PipelineManager.add.
  • The WebGLRenderer.setPipeline method no longer exists, instead use PipelineManager.set.
  • The WebGLRenderer.rebindPipeline method no longer exists, instead use PipelineManager.rebind.
  • The WebGLRenderer.clearPipeline method no longer exists, instead use PipelineManager.clear.

The Pipeline Manager also offers the following new features:

  • The PipelineManager.resize method automatically handles resize events across all pipelines.
  • The PipelineManager.preRender method calls the pre-render method of all pipelines.
  • The PipelineManager.render method calls the render method of all pipelines.
  • The PipelineManager.postRender method calls the post-render method of all pipelines.
  • The PipelineManager.setMulti method automatically binds the Multi Texture Pipeline, Phaser's default.
  • The PipelineManager.clear method will clear the pipeline, store it in previous and free the renderer.
  • The PipelineManager.rebind method will reset the rendering context and restore the previous pipeline, if set.

New constants have been created to help you reference a pipeline without needing to use strings:

  • Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE for the Bitmap Mask Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE for the Light 2D Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE for the Single Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE for the Multi Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE for the Rope Pipeline.

All Game Objects have been updated to use the new constants and Pipeline Manager.

Single Pipeline

There is also a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGL Multi-Texture Rendering

The Multi Pipeline (previously called the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw-call bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLPipeline.forceZero is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.

Light Pipeline Changes

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh and Quad Game Objects now support rendering with normal maps.
  • The Graphics Game Objects now support rendering in Light2d. You can even use normal map textures for the texture fills.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • All Shape Game Objects (Rectangle, IsoBox, Star, Polygon, etc) now support rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Both Static and Dynamic Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Lights

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

WebGL ModelViewProjection API Changes

The ModelViewProjection object contained a lot of functions that Phaser never used internally. These have now been moved to external functions, which can be easily excluded from Custom builds to save space.

If you used any of them in your code, please update to the new function names below:

  • Phaser.Renderer.WebGL.MVP is a new namespace under which the Model View Projection functions now live.
  • projIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectIdentity
  • projPersp is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectPerspective
  • modelRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateX
  • modelRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateY
  • modelRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateZ
  • viewLoad is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad
  • viewRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateX
  • viewRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateY
  • viewRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateZ
  • viewScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewScale
  • viewTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewTranslate
  • modelIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Identity
  • modelScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Scale
  • modelTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Translate
  • viewIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewIdentity
  • viewLoad2D is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad2D
  • projOrtho is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectOrtho
  • Phaser.Renderer.WebGL.MVP.SetIdentity is a new function the others use, to save on space.

BitmapText - New Features, Updates and API Changes

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.
  • You can now use setMaxWidth on DynamicBitmapText, which wasn't previously possible. Fix #4997 (thanks @AndreaBoeAbrahamsen)

Update List Changes

The way in which Game Objects add themselves to the Scene Update List has changed. Instead of being added by the Factory methods, they will now add and remove themselves based on the new ADDED_TO_SCENE and REMOVED_FROM_SCENE events. This means, you can now add Sprites directly to a Container, or Group, and they'll animate properly without first having to be part of the Display List. The full set of changes and new features relating to this follow:

  • GameObjects.Events.ADDED_TO_SCENE is a new event, emitted by a Game Object, when it is added to a Scene, or a Container that is part of the Scene.
  • GameObjects.Events.REMOVED_FROM_SCENE is a new event, emitted by a Game Object, when it is removed from a Scene, or a Container that is part of the Scene.
  • Scenes.Events.ADDED_TO_SCENE is a new event, emitted by a Scene, when a new Game Object is added to the display list in the Scene, or a Container that is on the display list.
  • Scenes.Events.REMOVED_FROM_SCENE is a new event, emitted by a Scene, when it a Game Object is removed from the display list in the Scene, or a Container that is on the display list.
  • GameObject.addedToScene is a new method that custom Game Objects can use to perform additional set-up when a Game Object is added to a Scene. For example, Sprite uses this to add itself to the Update List.
  • GameObject.removedFromScene is a new method that custom Game Objects can use to perform additional tear-down when a Game Object is removed from a Scene. For example, Sprite uses this to remove themselves from the Update List.
  • Game Objects no longer automatically remove themselves from the Update List during preDestroy. This should be handled directly in the removedFromScene method now.
  • The Container will now test to see if any Game Object added to it is already on the display list, or not, and emit its ADDED and REMOVED events accordingly. Fix #5267 #3876 (thanks @halgorithm @mbpictures)
  • DisplayList.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • DisplayList.addChildCallback is a new method that overrides the List callback and fires the new ADDED events.
  • DisplayList.removeChildCallback is a new method that overrides the List callback and fires the new REMOVED events.
  • GameObjectCreator.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • GameObjectFactory.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • ProcessQueue.checkQueue is a new boolean property that will make sure only unique objects are added to the Process Queue.
  • The Update List now uses the new checkQueue property to ensure no duplicate objects are on the active list.
  • DOMElementFactory, ExternFactory, ParticleManagerFactor, RopeFactory and SpriteFactory all no longer add the objects to the Update List, this is now handled by the ADDED events instead.
  • Sprite, Rope, ParticleEmitterManager, Extern and DOMElement now all override the addedToScene and removedFromScene callbacks to handle further set-up tasks.

Spine Plugin Updates

  • The Spine Runtimes have been updated to 3.8.99, which are the most recent non-beta versions. Please note, you will need to re-export your animations if you're working in a version of Spine lower than 3.8.20.
  • SpineContainer is a new Game Object available via this.add.spineContainer to which you can add Spine Game Objects only. It uses a special rendering function to retain batching, even across multiple container or Spine Game Object instances, resulting in dramatically improved performance over using regular Containers.
  • A Spine Game Object with setVisible(false) will no longer still cause internal gl commands and is now properly skipped, retaining any current batch in the process. Fix #5174 (thanks @Kitsee)
  • The Spine Game Object WebGL Renderer will no longer clear the type if invisible and will only end the batch if the next type doesn't match.
  • The Spine Game Object WebGL Renderer will no longer rebind the pipeline if it was the final object on the display list, saving lots of gl commands.
  • The Webpack build scripts have all been updated for Webpack 4.44.x. Fix #5243 (thanks @RollinSafary)
  • There is a new npm script npm run plugin.spine.runtimes which will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo into plugins/spine/ in order for this to work and then run npm i.
  • Spine Game Objects can now be rendered to Render Textures. Fix #5184 (thanks @Kitsee)
  • Using > 128 Spine objects in a Container would cause a WebGL: INVALID_OPERATION: vertexAttribPointer: no ARRAY_BUFFER is bound and offset is non-zero error if you added any subsequent Spine objects to the Scene. There is now no limit. Fix #5246 (thanks @d7561985)
  • The Spine Plugin will now work in HEADLESS mode without crashing. Fix #4988 (thanks @raimon-segura)
  • Spine Game Objects now use -1 as their default blend mode, which means 'skip setting it'.
  • The Spine TypeScript defs have been updated for the latest version of the plugin and to add SpineContainers.
  • The SpineGameObject.setAnimation method will now use the trackIndex parameter if ignoreIfPlaying is set and run the check against this track index. Fix #4842 (thanks @vinerz)
  • The SpineFile will no longer throw a warning if adding a texture into the Texture Manager that already exists. This allows you to have multiple Spine JSON use the same texture file, however, it also means you now get no warning if you accidentally load a texture that exists, so be careful with your keys! Fix #4947 (thanks @Nomy1)
  • The Spine Plugin destroy method will now no longer remove the Game Objects from the Game Object Factory, or dispose of the Scene Renderer. This means when a Scene is destroyed, it will keep the Game Objects in the factory for other Scene's to use. Fix #5279 (thanks @Racoonacoon)
  • SpinePlugin.gameDestroy is a new method that is called if the Game instance emits a destroy event. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.
  • SpineFile will now check to see if another identical atlas in the load queue is already loading the texture it needs and will no longer get locked waiting for a file that will never complete. This allows multiple skeleton JSONs to use the same atlas data. Fix #5331 (thanks @Racoonacoon)
  • SpineFile now uses a ! character to split the keys, instead of an underscore, preventing the plugin from incorrectly working out the keys for filenames with underscores in them. Fix #5336 (thanks @Racoonacoon)

Animation API - New Features and Updates

If you use Animations in your game, please read the following important API changes in 3.50:

The Animation API has had a significant overhaul to improve playback handling. Instead of just playing an animation based on its global key, you can now supply a new PlayAnimationConfig object instead, which allows you to override any of the default animation settings, such as duration, delay and yoyo (see below for the full list). This means you no longer have to create lots of duplicate animations just to change properties such as duration, and can now set them dynamically at run-time as well.

  • The Animation class no longer extends EventEmitter, as it no longer emits any events directly. This means you cannot now listen for events directly from an Animation instance. All of the events are now dispatched by the Game Objects instead.
  • All of the SPRITE_ANIMATION_KEY events have been removed. Instead, please use the new events which all carry the frameKey parameter, which can be used to handle frame specific events. The only exception to this is ANIMATION_COMPLETE_KEY, which is a key specific version of the completion event.
  • ANIMATION_UPDATE_EVENT is a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.
  • ANIMATION_STOP_EVENT is a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of the stop methods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)
  • The Game Object Component.Animation component has been renamed to AnimationState and has moved namespace. It's now in Phaser.Animations instead of GameObjects.Components to help differentiate it from the Animation class when browsing the documentation.
  • The play, playReverse, playAfterDelay, playAfterRepeat and chain Sprite and Animation Component methods can now all take a Phaser.Types.Animations.PlayAnimationConfig configuration object, as well as a string, as the key parameter. This allows you to override any default animation setting with those defined in the config, giving you far greater control over animations on a Game Object level, without needing to globally duplicate them.
  • AnimationState.create is a new method that allows you to create animations directly on a Sprite. These are not global and never enter the Animation Manager, instead risiding within the Sprite itself. This allows you to use the same keys across both local and global animations and set-up Sprite specific local animations.
  • AnimationState.generateFrameNumbers is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • AnimationState.generateFrameNames is a new method that is a proxy for the same method available under the Animation Manager. It's exposed in the Animation State so you're able to access it from within a Sprite (thanks @juanitogan)
  • All playback methods: play, playReverse, playAfterDelay and playAfterRepeat will now check to see if the given animation key exists locally on the Sprite first. If it does, it's used, otherwise it then checks the global Animation Manager for the key instead.
  • AnimationState.skipMissedFrames is now used when playing an animation, allowing you to create animations that run at frame rates far exceeding the refresh rate, or that will update to the correct frame should the game lag. Feature #4232 (thanks @colorcube)
  • AnimationManager.addMix is a new method that allows you to create mixes 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.
  • AnimationManager.getMix is a new method that will return the mix duration between the two given animations.
  • AnimationManager.removeMix is a new method that will remove the mixture between either two animations, or all mixtures for the given animation.
  • AnimationState.remove is a new method that will remove a locally stored Animation instance from a Sprite.
  • AnimationState.get is a new method that will return a locally stored Animation instance from the Sprite.
  • AnimationState.exists is a new method that will check if a locally stored Animation exists on the Sprite.
  • The internal AnimationState.remove method has been renamed to globalRemove.
  • AnimationState.textureManager is a new property that references the global Texture Manager.
  • AnimationState.anims is a new property that contains locally created Animations in a Custom Map.
  • AnimationState.play and Sprite.play no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • AnimationState.playReverse and Sprite.playReverse no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • The AnimationState.delayedPlay method has been renamed to playAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration.
  • The AnimationState.stopOnRepeat method has been renamed to stopAfterRepeat
  • The AnimationState.getCurrentKey method has been renamed to getName.
  • AnimationState.getFrameName is a new method that will return the key of the current Animation Frame, if an animation has been loaded.
  • AnimationState.playAfterDelay and Sprite.playAfterDelay are new methods that will play the given animation after the delay in ms expires.
  • AnimationState.playAfterRepeat and Sprite.playAfterRepeat are new methods that will play the given animation after the current animation finishes repeating. You can also specify the number of repeats allowed left to run.
  • The AnimationState.chain method is now available on the Sprite class.
  • The AnimationState.stopAfterDelay method is now available on the Sprite class.
  • The AnimationState.stopAfterRepeat method is now available on the Sprite class.
  • The AnimationState.stopOnFrame method is now available on the Sprite class.
  • AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser. Please see the comprehensive documentation for this method for full details on how to do this.
  • AnimationState now handles all of the loading of the animation. It no longer has to make calls out to the Animation Manager or Animation instance itself and will load the animation data directly, replacing as required from the optional PlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.
  • The PlayAnimationConfig.frameRate property lets you optionally override the animation frame rate.
  • The PlayAnimationConfig.duration property lets you optionally override the animation duration.
  • The PlayAnimationConfig.delay property lets you optionally override the animation delay.
  • The PlayAnimationConfig.repeat property lets you optionally override the animation repeat counter.
  • The PlayAnimationConfig.repeatDelay property lets you optionally override the animation repeat delay value.
  • The PlayAnimationConfig.yoyo property lets you optionally override the animation yoyo boolean.
  • The PlayAnimationConfig.showOnStart property lets you optionally override the animation show on start value.
  • The PlayAnimationConfig.hideOnComplete property lets you optionally override the animation hide on complete value.
  • The PlayAnimationConfig.startFrame property lets you optionally set the animation frame to start on.
  • The PlayAnimationConfig.timeScale property lets you optionally set the animation time scale factor.
  • AnimationState.delayCounter is a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animation START events fire. Fix #4426 (thanks @bdaenen)
  • AnimationState.hasStarted is a new boolean property that allows you to tell if the current animation has started playing, or is still waiting for a delay to expire.
  • AnimationState.showOnStart is a new boolean property that controls if the Game Object should have setVisible(true) called on it when the animation starts.
  • AnimationState.hideOnComplete is a new boolean property that controls if the Game Object should have setVisible(false) called on it when the animation completes.
  • The AnimationState.chain method docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does!
  • The AnimationState.setDelay method has been removed. It never actually worked and you can now perform the same thing by calling either playAfterDelay or setting the delay property in the play config.
  • The AnimationState.getDelay method has been removed. You can now read the delay property directly.
  • The AnimationState.setRepeat method has been removed. You can achieve the same thing by setting the repeat property in the play config, or adjusting the public repeatCounter property if the animation has started.
  • AnimationState.handleStart is a new internal private method that handles the animation start process.
  • AnimationState.handleRepeat is a new internal private method that handles the animation repeat process.
  • AnimationState.handleStop is a new internal private method that handles the animation stop process.
  • AnimationState.handleComplete is a new internal private method that handles the animation complete process.
  • AnimationState.emitEvents is a new internal private method that emits animation events, cutting down on duplicate code.
  • The AnimationState.restart method has a new optional boolean parameter resetRepeats which controls if you want to reset the repeat counter during the restart, or not.
  • Animation.getTotalFrames is a new method that will return the total number of frames in the animation. You can access it via this.anims.currentAnim.getTotalFrames from a Sprite.
  • Animation.calculateDuration is a new method that calculates the duration, frameRate and msPerFrame for a given animation target.
  • The BuildGameObjectAnimation function now uses the PlayAnimationConfig object to set the values.
  • Sprite.playReverse is a new method that allows you to play the given animation in reverse on the Sprite.
  • Sprite.playAfterDelay is a new method that allows you to play the given animation on the Sprite after a delay.
  • Sprite.stop is a new method that allows you to stop the current animation on the Sprite.
  • AnimationManager.load has been removed as it's no longer required.
  • AnimationManager.staggerPlay has been fixed so you can now pass in negative stagger values.
  • AnimationManager.staggerPlay has a new optional boolean parameter staggerFirst, which allows you to either include or exclude the first child in the stagger calculations.
  • The Animation.completeAnimation method has been removed as it's no longer required.
  • The Animation.load method has been removed as it's no longer required.
  • The Animation.setFrame method has been removed as it's no longer required.
  • The Animation.getFirstTick method has no longer needs the includeDelay parameter, as it's handled by AnimationState now.
  • The Animation.getFrames method has a new optional boolean parameter sortFrames which will run a numeric sort on the frame names after constructing them, if a string-based frame is given.
  • Types.Animations.Animation has a new boolean property sortFrames, which lets Phaser numerically sort the generated frames.
  • AnimationState.timeScale is a new public property that replaces the old private _timeScale property.
  • AnimationState.delay is a new public property that replaces the old private _delay property.
  • AnimationState.repeat is a new public property that replaces the old private _repeat property.
  • AnimationState.repeatDelay is a new public property that replaces the old private _repeatDelay property.
  • AnimationState.yoyo is a new public property that replaces the old private _yoyo property.
  • AnimationState.inReverse is a new public property that replaces the old private _reverse property.
  • AnimationState.startAnimation is a new public method that replaces the old private _startAnimation method.
  • The AnimationState.getProgress method has been fixed so it will return correctly if the animation is playing in reverse.
  • The AnimationState.globalRemove method will now always be called when an animation is removed from the global Animation Manager, not just once.
  • The AnimationState.getRepeat method has now been removed. You can get the value from the repeat property.
  • The AnimationState.setRepeatDelay method has now been removed. You can set the value using the repeatDelay config property, or changing it at run-time.
  • AnimationState.complete is a new method that handles the completion in animation playback.
  • The AnimationState.setTimeScale method has now been removed. You can set the value using the timeScale config property, or changing it at run-time.
  • The AnimationState.getTimeScale method has now been removed. You can read the value using the timeScale property.
  • The AnimationState.getTotalFrames method has been fixed and won't error if called when no animation is loaded.
  • The AnimationState.setYoyo method has now been removed. You can set the value using the yoyo config property, or changing it at run-time.
  • The AnimationState.getYoyo method has now been removed. You can read the value using the yoyo property.
  • The AnimationState.stopAfterRepeat method now has an optional parameter repeatCount, so you can tell the animation to stop after a specified number of repeats, not just 1.
  • When playing an animation in reverse, if it reached the first frame and had to repeat, it would then jump to the frame before the final frame and carry on, skipping out the final frame.
  • The AnimationState.updateFrame method has now been removed. Everything is handled by setCurrentFrame instead, which removes one extra step out of the update process.
  • GenerateFrameNames will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers would include the __BASE frame by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.
  • GenerateFrameNumbers can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.
  • GenerateFrameNames can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.

Tilemap - New Features, Updates and API Changes

The Tilemap system now supports isometric, hexagonal and staggered map types, along with the previous orthogonal format, thanks to a PR from @svipal.

You can now export maps using any of these orientations from the Tiled Map Editor and load them into Phaser using the standard tilemap loading API.

The following are all of the new components and functions that made this possible:

  • Phaser.Types.Tilemaps.TilemapOrientationType is a new type def that holds the 4 types of map orientation now supported.
  • The Tile.updatePixelXY method now updates the tile XY position based on map type.
  • Tilemap.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • DynamicTilemapLayer.isoCullDistances is a new Vector2 property that allows you to control how far the tiles will still be rendered for, out of the camera bounds, before they are culled.
  • StaticTilemapLayer.isoCullDistances is a new Vector2 property that allows you to control how far the tiles will still be rendered for, out of the camera bounds, before they are culled.
  • LayerData.orientation is a new property that holds the tilemap layers orientation constant.
  • LayerData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • MapData.orientation is a new property that holds the tilemap layers orientation constant.
  • MapData.hexSideLength is a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.
  • Tilemaps.Components.HexagonalWorldToTileY is a new function that converts a world Y coordinate to hexagonal tile Y coordinate.
  • Tilemaps.Components.StaggeredWorldToTileY is a new function that converts a world Y coordinate to staggered tile Y coordinate.
  • Tilemaps.Components.HexagonalWorldToTileXY is a new function that converts world coordinates to hexagonal tile coordinates.
  • Tilemaps.Components.IsometricWorldToTileXY is a new function that converts world coordinates to isometric tile coordinates.
  • Tilemaps.Components.StaggeredWorldToTileXY is a new function that converts world coordinates to staggered tile coordinates.
  • Tilemaps.Components.HexagonalTileToWorldY is a new function that converts a hexagonal Y coordinate to a world coordinate.
  • Tilemaps.Components.StaggeredTileToWorldY is a new function that converts a staggered Y coordinate to a world coordinate.
  • Tilemaps.Components.HexagonalTileToWorldXY is a new function that converts hexagonal tile coordinates to world coordinates.
  • Tilemaps.Components.IsometricTileToWorldXY is a new function that converts isometric tile coordinates to world coordinates.
  • Tilemaps.Components.StaggeredTileToWorldXY is a new function that converts staggered tile coordinates to world coordinates.
  • Tilemaps.Components.GetTileToWorldXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetTileToWorldXXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetWorldToTileXYFunction is a new function that returns the correct conversion function to use.
  • Tilemaps.Components.GetCullTilesFunction is a new function that returns the correct culling function to use.
  • Tilemaps.Components.HexagonalCullTiles is a new function that culls tiles in a hexagonal map.
  • Tilemaps.Components.StaggeredCullTiles is a new function that culls tiles in a staggered map.
  • Tilemaps.Components.IsometricCullTiles is a new function that culls tiles in a isometric map.
  • Tilemaps.Components.CullBounds is a new function that calculates the cull bounds for an orthogonal map.
  • Tilemaps.Components.HexagonalCullBounds is a new function that calculates the cull bounds for a hexagonal map.
  • Tilemaps.Components.StaggeredCullBounds is a new function that calculates the cull bounds for a staggered map.
  • Tilemaps.Components.RunCull is a new function that runs the culling process from the combined bounds and tilemap.
  • Tilemap._convert is a new internal private hash of tilemap conversion functions used by the public API.

Mesh Game Object - New Features, Updates and API Changes

The Mesh Game Object has been rewritten from scratch in v3.50 with a lot of changes to make it much more useful. It is accompanied by the new Geom.Mesh set of functions.

  • Geom.Mesh is a new namespace that contains the Mesh related geometry functions. These are stand-alone functions that you may, or may not require, depending on your game.
  • Geom.Mesh.Vertex is a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.
  • Geom.Mesh.Face is a new class that consists of references to the three Vertex instances that construct a single Face in a Mesh and provides methods for manipulating them.
  • Geom.Mesh.GenerateVerts is a new function that will return an array of Vertex and Face objects generated from the given data. You can provide index, or non-index vertex lists, along with UV data, normals, colors and alpha which it will parse and return the results from.
  • Geom.Mesh.GenerateGridVerts is a new function that will generate a series of Vertex objects in a grid format, based on the given GenerateGridConfig config file. You can set the size of the grid, the number of segments to split it into, translate it, color it and tile the texture across it. The resulting data can be easily used by a Mesh Game Object.
  • Geom.Mesh.GenerateObjVerts is a new function that will generate a series of Vertex objects based on the given parsed Wavefront Obj Model data. You can optionally scale and translate the generated vertices and add them to a Mesh.
  • Geom.Mesh.ParseObj is a new function that will parse a triangulated Wavefront OBJ file into model data into a format that the GenerateObjVerts function can consume.
  • Geom.Mesh.ParseObjMaterial is a new function that will parse a Wavefront material file and extract the diffuse color data from it, combining it with the parsed object data.
  • Geom.Mesh.RotateFace is a new function that will rotate a Face by a given amount, based on an optional center of rotation.
  • Loader.OBJFile is a new File Loader type that can load triangulated Wavefront OBJ files, and optionally material files, which are then parsed and stored in the OBJ Cache.
  • The Mesh constructor and MeshFactory signatures have changed to scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first. indicies is a new parameter that allows you to provide indexed vertex data to create the Mesh from, where the indicies array holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. The indicies array is optional. If your data is not indexed, then simply pass null or an empty array for this parameter.
  • The Mesh Game Object now has the Animation State Component. This allows you to create and play animations across the texture of a Mesh, something that previously wasn't possible. As a result, the Mesh now adds itself to the Update List when added to a Scene.
  • Mesh.addVertices is a new method that allows you to add vertices to a Mesh Game Object based on the given parameters. This allows you to modify a mesh post-creation, or populate it with data at a later stage.
  • Mesh.addVerticesFromObj is a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the new OBJFile with a this.load.obj call, then you can use the key with this method. This method also takes an optional scale and position parameters to control placement of the created model within the Mesh.
  • Mesh.hideCCW is a new boolean property that, when enabled, tells a Face to not render if it isn't counter-clockwise. You can use this to hide backward facing Faces.
  • Mesh.modelPosition is a new Vector3 property that allows you to translate the position of all vertices in the Mesh.
  • Mesh.modelRotation is a new Vector3 property that allows you to rotate all vertices in the Mesh.
  • Mesh.modelScale is a new Vector3 property that allows you to scale all vertices in the Mesh.
  • Mesh.panX is a new function that will translate the view position of the Mesh on the x axis.
  • Mesh.panY is a new function that will translate the view position of the Mesh on the y axis.
  • Mesh.panZ is a new function that will translate the view position of the Mesh on the z axis.
  • Mesh.updateProjectionMatrix is a new method that allows you to set the projection matrix based on the given size, fov, near and far values.
  • Mesh.clear is a new method that will destroy all Faces and Vertices and clear the Mesh.
  • Mesh.depthSort is a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.
  • Mesh.addVertex is a new method that allows you to add a new single Vertex into the Mesh.
  • Mesh.addFace is a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.
  • Mesh.getFaceCount new is a new method that will return the total number of Faces in the Mesh.
  • Mesh.getVertexCount new is a new method that will return the total number of Vertices in the Mesh.
  • Mesh.getFace new is a new method that will return a Face instance from the Mesh based on the given index.
  • Mesh.getFaceAt new is a new method that will return an array of Face instances from the Mesh based on the given position. The position is checked against each Face, translated through the optional Camera and Mesh matrix. If more than one Face intersects, they will all be returned but the array will be depth sorted first, so the first element will be that closest to the camera.
  • Mesh.vertices is now an array of GameObject.Vertex instances, not a Float32Array.
  • Mesh.faces is a new array of GameObject.Face instances, which is populated during a call to methods like addVertices or addModel.
  • Mesh.totalRendered is a new property that holds the total number of Faces that were rendered in the previous frame.
  • Mesh.setDebug is a new method that allows you to render a debug visualisation of the Mesh vertices to a Graphics Game Object. You can provide your own Graphics instance and optionally callback that is invoked during rendering. This allows you to easily visualise the vertices of your Mesh to help debug UV mapping.
  • The Mesh now renders by iterating through the Faces array, not the vertices. This allows you to use Array methods such as BringToTop to reposition a Face, thus changing the drawing order without having to repopulate all of the vertices. Or, for a 3D model, you can now depth sort the Faces.
  • The Mesh Game Object now extends the SingleAlpha component and the alpha value is factored into the final alpha value per vertex during rendering. This means you can now set the whole alpha across the Mesh using the standard setAlpha methods. But, if you wish to, you can still control the alpha on a per-vertex basis as well.
  • The Mesh renderer will now check to see if the pipeline capacity has been exceeded for every Face added, allowing you to use Meshes with vertex counts that exceed the pipeline capacity without causing runtime errors.
  • You can now supply just a single numerical value as the colors parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the color for all vertices created.
  • You can now supply just a single numerical value as the alphas parameter in the constructor, factory method and addVertices method. If a number, instead of an array, it will be used as the alpha for all vertices created.
  • Mesh.debugGraphic is a new property that holds the debug Graphics instance reference.
  • Mesh.debugCallback is a new property that holds the debug render callback.
  • Mesh.renderDebugVerts is a new method that acts as the default render callback for setDebug if none is provided.
  • Mesh.preDestroy is a new method that will clean-up the Mesh arrays and debug references on destruction.
  • Mesh.isDirty is a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically in preUpdate to avoid generating lots of math when nothing has changed.
  • The Mesh.uv array has been removed. All UV data is now bound in the Vertex instances.
  • The Mesh.colors array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.alphas array has been removed. All color data is now bound in the Vertex instances.
  • The Mesh.tintFill property is now a boolean and defaults to false.

Quad Game Object Removed

The Quad Game Object has been removed from v3.50.0.

You can now create your own Quads easily using the new Geom.Mesh.GenerateGridVerts function, which is far more flexible than the old quads were.

Input / Mouse Updates and API Changes

  • ScaleManager.refresh is now called when the Game.READY event fires. This fixes a bug where the Scale Manager would have the incorrect canvas bounds, because they were calculated before a previous canvas was removed from the DOM. Fix #4862 (thanks @dranitski)
  • The Game Config property inputMouseCapture has been removed, as this is now split into 3 new config options:
  • inputMousePreventDefaultDown is a new config option that allows you to control preventDefault calls specifically on mouse down events. Set it via input.mouse.preventDefaultDown in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultUp is a new config option that allows you to control preventDefault calls specifically on mouse up events. Set it via input.mouse.preventDefaultUp in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultMove is a new config option that allows you to control preventDefault calls specifically on mouse move events. Set it via input.mouse.preventDefaultMove in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultWheel is a new config option that allows you to control preventDefault calls specifically on mouse wheel events. Set it via input.mouse.preventDefaultWheel in the Game Config. It defaults to true, the same as the previous capture property did.
  • The MouseManager.capture property has been removed, as this is now split into 3 new config options (see below)
  • MouseManager.preventDefaultDown is a new boolean property, set via the inputMousePreventDefaultDown config option that allows you to toggle capture of mouse down events at runtime.
  • MouseManager.preventDefaultUp is a new boolean property, set via the inputMousePreventDefaultUp config option that allows you to toggle capture of mouse up events at runtime.
  • MouseManager.preventDefaultMove is a new boolean property, set via the inputMousePreventDefaultMove config option that allows you to toggle capture of mouse move events at runtime.
  • MouseManager.preventDefaultWheel is a new boolean property, set via the inputMousePreventDefaultWheel config option that allows you to toggle capture of mouse wheel at runtime.
  • In the MouseManager the up, down and move events are no longer set as being passive if captured. Over, Out, Wheel and the Window level Down and Up events are always flagged as being passive. Wheel events are non-passive if capturing is enabled.
  • The GamepadPlugin will now call refreshPads as part of its start process. This allows you to use Gamepads across multiple Scenes, without having to wait for a connected event from each one of them. If you've already had a connected event in a previous Scene, you can now just read the pads directly via this.input.gamepad.pad1 and similar. Fix #4890 (thanks @Sytten)
  • Shutting down the Gamepad plugin (such as when sleeping a Scene) no longer calls GamepadPlugin.disconnectAll, but destroying it does.
  • Gamepad._created is a new private internal property that keeps track of when the instance was created. This is compared to the navigator timestamp in the update loop to avoid event spamming. Fix #4890.
  • Pointer.down will now check if the browser is running under macOS and if the ctrl key was also pressed, if so, it will flag the down event as being a right-click instead of a left-click, as per macOS conventions. Fix #4245 (thanks @BigZaphod)
  • When destroying an interactive Game Object that had useHandCursor enabled, it would reset the CSS cursor to default, even if the cursor wasn't over that Game Object. It will now only reset the cursor if it's over the Game Object being destroyed. Fix #5321 (thanks @JstnPwll)
  • The InputPlugin.shutdown method will now reset the CSS cursor, in case it was set by any Game Objects in the Scene that have since been destroyed.
  • The InputPlugin.processOverEvents has had a duplicate internal loop removed from it (thanks KingCosmic)

Tint Updates and Shader Changes

Phaser has had the ability to apply an additive tint to a Game Object since the beginning, and gained 'filled tints', with and without texture alpha, in v3.11. While this was handy, it introduced a 3-way if-else condition to the shaders to handle the different modes. Plus, setting tint colors was also generating rgb order Float32 color values for each Game Object, making reading those colors back again difficult (as they'd return in BGR order).

This has all changed in 3.50, as outlined below. Tint values are now used directly in the shader and don't pass through a color conversion function first. Lots of private properties have been removed and the shaders no longer have a 3-way if-else block. All of this means improved performance and a slight reduction in memory overhead.

  • Tint.tintTopLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTL which has now been removed.
  • Tint.tintTopRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTR which has now been removed.
  • Tint.tintBottomLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBL which has now been removed.
  • Tint.tintBottomRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBR which has now been removed.
  • The property Tint._isTinted has been removed as it's no longer required.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they now read the color value as outTint.bgr instead of outTint.rgb. This allows the colors to remain in RGB order within the Tint component.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they no longer have a 3-way check on the outTintEffect value.
  • The Multi Pipeline, Bitmap Text, Render Texture, Text, TileSprite and Camera now all read the tint values from the public properties instead of the private _tintTL etc ones. They also now set the tintEffect value directly from the tintFill property, removing another conditional check.
  • The function GetColorFromValue has been removed as it's no longer used internally.
  • The Rope.tintFill property is now a boolean, not an integer, and can no longer take 2 as a value for a complete fill. Instead, you should provide a solid color texture with no alpha.
  • As a result of the change to the shader, all uses of the WebGL Util function getTintAppendFloatAlphaAndSwap have been replaced with getTintAppendFloatAlpha instead.
  • As a result of the change to the shader, the Multi Pipeline now uses the WebGLRenderer.whiteTexture and tintEffect mode of 1 by default, instead of mode 2 (which has been removed) and a transparent texture. This ensures Graphics and Shapes objects still render correctly under the new smaller shader code.
  • WebGLRenderer.whiteTexture is a new property that is a reference to a pure white 4x4 texture that is created during Boot by the Texture Manager. The Multi Pipeline uses this internally for all Graphic, Shape and fill rendering.
  • The TextureManager now generates a new texture with the key __WHITE durings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines.
  • Config.images.white is a new Game Config property that specifies the 4x4 white PNG texture used by Graphics rendering. You can override this via the config, but only do so if needed.

Arcade Physics Updates

Prior to v3.50 an Arcade Physics Body could be one of two states: immovable, or moveable. An immovable body could not receive any impact from another Body. If something collided with it, it wouldn't even separate to break free from the collision (the other body had to take the full separation value). It was intended for objects such as platforms, ground or walls, there they absolutely shouldn't move under any circumstances. As a result, two immovable bodies could never be collided together. While this worked for scenery-like items, it didn't work if you required maybe 2 players who could collide with each other, but should never be able to push one another. As of 3.50 all physics bodies now have a new property pushable that allows this. A pushable body can share separation with its collider, as well as take on mass-based velocity from the impact. A non-pushable body will behave differently depending on what it collides with. For example, a pushable body hitting a non-pushable (or immoveable) body will rebound off it.

  • The Arcade Physics Body class has a new boolean property pushable (true, by default). This allows you to set if a Body can be physically pushed by another Body, or not. Fix #4175 #4415 (thanks @inmylo @CipSoft-Components)
  • Body.setPushable is a new chainable method that allows you to set the pushable state of a Body.
  • Arcade.Components.Pushable is a new component, inherited by the standard Arcade Physics Image and Sprite classes.
  • Bodies will now check to see if they are blocked in the direction they're being pushed, before resolving the collision. This helps stop some bodies from being pushed into other objects.
  • Bodies will now check which direction they were moving and separate accordingly. This helps stop some bodies from being pushed into other objects.
  • ArcadePhysics.disableUpdate is a new method that will prevent the Arcade Physics World update method from being called when the Scene updates. By disabling it, you're free to call the update method yourself, passing in your own delta and time values.
  • ArcadePhysics.enableUpdate is a new method that will make the Arcade Physics World update in time with the Scene update. This is the default, so only call this if you have specifically disabled it previously.
  • ArcadeWorldConfig.customUpdate is a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. If true the World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)
  • Physics.Arcade.Body.setCollideWorldBounds now has a new optional parameter onWorldBounds which allows you to enable the Body's onWorldBounds property in the same call (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityX is a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityY is a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)
  • The PhysicsGroup config now has two new optional properties maxVelocityX and maxVelocityY which allows you to set the maximum velocity on bodies added to the Group (thanks @samme)
  • The Arcade.Body.resetFlags method has a new optional boolean parameter clear. If set, it clears the wasTouching flags on the Body. This happens automatically when Body.reset is called. Previous to this, the flags were not reset until the next physics step (thanks @samme)
  • Physics.Arcade.ProcessX is a new set of functions, called by the SeparateX function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Physics.Arcade.ProcessY is a new set of functions, called by the SeparateY function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Arcade.Body.center values were incorrect after collisions with the world bounds or (for rectangular bodies) after collisions with another body. The body center is now updated after those separations (thanks @samme)

Loader Cache Changes

When loading any of the file types listed below it will no longer store the data file in the cache. For example, when loading a Texture Atlas using a JSON File, it used to store the parsed image data in the Texture Manager and also store the JSON in the JSON Cache under the same key. This has changed in 3.50. The data files are no longer cached, as they are not required by the textures once parsing is completed, which happens during load. This helps free-up memory. How much depends on the size of your data files. And also allows you to easily remove textures based on just their key, without also having to clear out the corresponding data cache.

  • AtlasJSONFile no longer stores the JSON in the JSON Cache once the texture has been created.
  • AtlasXMLFile no longer stores the XML in the XML Cache once the texture has been created.
  • UnityAtlasFile no longer stores the Text in the Text Cache once the texture has been created.
  • BitmapFontFile no longer stores the XML in the XML Cache once the texture has been created.
  • You can now use TextureManager.remove to remove a texture and not have to worry about clearing the corresponding JSON or XML cache entry as well in order to reload a new texture using the same key. Fix #5323 (thanks @TedGriggs)

Removal of 'resolution' property from across the API

For legacy reasons, Phaser 3 has never properly supported HighDPI devices. It will render happily to them of course, but wouldn't let you set a 'resolution' for the Canvas beyond 1. Earlier versions of 3.x had a resolution property in the Game Config, but it was never fully implemented (for example, it would break zooming cameras). When the Scale Manager was introduced in v3.16 we forced the resolution to be 1 to avoid it breaking anything else internally.

For a long time, the 'resolution' property has been present - taunting developers and confusing new comers. In this release we have finally gone through and removed all references to it. The Game Config option is now gone, it's removed from the Scale Manager, Base Camera and everywhere else where it matters. As much as we would have liked to implement the feature, we've spent too long without it, and things have been built around the assumption it isn't present. The API just wouldn't cope with having it shoe-horned in at this stage. As frustrating as this is, it's even more annoying to just leave the property there confusing people and wasting CPU cycles. Phaser 4 has been built with HighDPI screens in mind from the very start, but it's too late for v3. The following changes are a result of this removal:

  • The Phaser.Scale.Events#RESIZE event no longer sends the resolution as a parameter.
  • The BaseCamera.resolution property has been removed.
  • The internal private BaseCamera._cx, _cy, _cw and _ch properties has been removed, use x, y, width and height instead.
  • The BaseCamera.preRender method no longer receives or uses the resolution parameter.
  • The Camera.preRender method no longer receives or uses the resolution parameter.
  • The CameraManager.onResize method no longer receives or uses the resolution parameter.
  • The Core.Config.resolution property has been removed.
  • The TextStyle.resolution property is no longer read from the Game Config. You can still set it via the Text Style config to a value other than 1, but it will default to this now.
  • The CanvasRenderer no longer reads or uses the Game Config resolution property.
  • The PipelineManager.resize method along with WebGLPipeline.resize and anything else that extends them no longer receives or uses the resolution parameter.
  • The WebGLRenderer.resize and onResize methods no longer receives or uses the resolution parameter.
  • The ScaleManager.resolution property has been removed and all internal use of it.

Removed 'interpolationPercentage' parameter from all render functions

Since v3.0.0 the Game Object render functions have received a parameter called interpolationPercentage that was never used. The renderers do not calculate this value and no Game Objects apply it, so for the sake of clairty, reducing code and removing complexity from the API it has been removed from every single function that either sent or expected the parameter. This touches every single Game Object and changes the parameter order as a result, so please be aware of this if you have your own custom Game Objects, or plugins, that implement their own render methods. In terms of surface API changes, you shouldn't notice anything at all from this removal.

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • WebGLRenderer.setInt1iv will allow you to look-up and set a 1iv uniform on the given shader.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.
  • You can now use this.renderer from within a Scene, as it's now a Scene-level property and part of the Injection Map.
  • Clock.addEvent can now take an existing TimerEvent object, as well as a config object. If a TimerEvent is given it will be removed from the Clock, reset and then added. This allows you to pool TimerEvents rather than constantly create and delete them. Fix #4115 (thanks @jcyuan)
  • Clock.removeEvent is a new method that allows you to remove a TimerEvent, or an array of them, from all internal lists of the current Clock.
  • Group.getMatching is a new method that will return any members of the Group that match the given criteria, such as getMatching('visible', true) (thanks @atursams)
  • Utils.Array.SortByDigits is a new function that takes the given array of strings and runs a numeric sort on it, ignoring any non-digits.
  • GroupCreateConfig, which is used when calling Group.createMultiple or Group.createFromConfig, can now accept the following new properties: setOrigin: { x, y, stepX, stepY } which are applied to the items created by the Group.
  • Transform.copyPosition is a new method that will copy the position from the given object to the Game Object (thanks @samme)
  • The Text.MeasureText function, which is used to calculate the ascent and descent of Text Game Objects whenever the style, or font size, is changed, has been updated to use the new actualBoundingBoxAscent functions present in modern browsers. This allows for significantly faster ascent calculations than previously. Older browsers, such as IE, will still fall back (thanks @rexrainbow)
  • GameObjects.GetCalcMatrix is a new function that is used to calculate the transformed Game Object matrix, based on the given Game Object, Camera and Parent. This function is now used by the following Game Objects: BitmapText (Static and Dynamic), Graphics, Extern, Mesh, Rope, Shader, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. This dramatically reduces the amount of duplicate code across the API.
  • Utils.Array.Matrix.Translate is a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.
  • Vertor3.addScale is a new method that will add the given vector and multiply it in the process.
  • When defining the ease used with a Particle Emitter you can now set easeParams in the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh)
  • BitmapMask.createMask is a new method that will internally create the WebGL textures and framebuffers required for the mask. This is now used by the constructor and if the context is lost. It now also clears any previous textures/fbos that may have been created first, helping prevent memory leaks.
  • BitmapMask.clearMask will delete any WebGL textures or framebuffers the mask is using. This is now called when the mask is destroyed, or a new mask is created upon it.
  • Quaternion now has a new property onChangeCallback which, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.
  • The Quaternion.set method has a new optional boolean parameter update (defaults to true), which will call the onChangeCallback if set.
  • Quaternion.setFromEuler is a new method that will set the quaternion from the given Euler object, optionally calling the onChangeCallback in the process.
  • Quaternion.setFromRotationMatrix is a new method that will set the rotation of the quaternion from the given Matrix4.
  • Vector3.setFromMatrixPosition is a new method that will set the components of the Vector3 based on the position of the given Matrix4.
  • Vector3.setFromMatrixColumn is a new method that will set the components of the Vector3 based on the specified Matrix4 column.
  • Vector3.fromArray is a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.
  • Vector3.min is a new method that will set the components of the Vector3 based on the Main.min between it and the given Vector3.
  • Vector3.max is a new method that will set the components of the Vector3 based on the Main.max between it and the given Vector3.
  • Vector3.addVectors is a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.
  • Vector3.addScalar is a new method that will multiply the components of the Vector3 by the scale value given.
  • Vector3.applyMatrix3 is a new method that will take a Matrix3 and apply it to the Vector3.
  • Vector3.applyMatrix4 is a new method that will take a Matrix4 and apply it to the Vector3.
  • Vector3.projectViewMatrix is a new method that multiplies the Vector3 by the given view and projection matrices.
  • Vector3.unprojectViewMatrix is a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.
  • Matrix4.setValues is a new method that allows you to set all of the matrix components individually. Most internal methods now use this.
  • Matrix.multiplyToMat4 is a new method that multiplies a Matrix4 by the given src Matrix4 and stores the results in the out Matrix4.
  • Matrix4.fromRotationXYTranslation is a new method that takes the rotation and position vectors and builds this Matrix4 from them.
  • Matrix4.getMaxScaleOnAxis is a new method that will return the maximum axis scale from the Matrix4.
  • Matrix4.lookAtRH is a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.
  • Matrix4.transform is a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.
  • Matrix4.multiplyMatrices is a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.
  • Matrix4.premultiply is a new method that takes a Matrix4 and multiplies it by the current Matrix4.
  • Matrix4.getInverse is a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.
  • WebGLRenderer.instancedArraysExtension is a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.
  • WebGLRenderer.vaoExtension is a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Earcut has now been exposed and is available via Geom.Polygon.Earcut and is fully documented.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.
  • Pointer.downTime now stores the event timestamp of when the first button on the input device was pressed down, not just when button 1 was pressed down.
  • Pointer.upTime now stores the event timestamp of when the final depressed button on the input device was released, not just when button 1 was released.
  • The Pointer.getDuration method now uses the new Pointer downTime and upTime values, meaning it will accurately report the duration of when any button is being held down, not just the primary one. Fix #5112 (thanks @veleek)
  • The BaseShader default vertex shader now includes the outTexCoord vec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok)
  • When using the GameObjectCreator for Containers you can now specify the children property in the configuration object.
  • WebGLRenderer.finalType is a new boolean property that signifies if the current Game Object being rendered is the final one in the list.
  • The WebGLRenderer.updateCanvasTexture method will now set gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL to true, which should stop issues where you update a Text Game Object, having added a Render Texture or Spine Game Object to the Scene after it, which switches the PMA setting. Fix #5064 #5155 (thanks @hugoruscitti @immangrove-supertree)
  • Textures.Parsers.JSONHash will now perform a hasOwnProperty check when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes from JSON.parse. Fix #4768 (thanks @RollinSafary)
  • The Camera3D Plugin has been rebuilt for Phaser 3.50 and the webpack config updated. This plugin is now considered deprecated and will not be updated beyond this release.
  • Tween.seek will no longer issue a console warning for 'Tween.seek duration too long', it's now up to you to check on the performance of tween seeking.
  • WebGLRenderer.previousPipeline is a new property that is set during a call to clearPipeline and used during calls to rebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.
  • The WebGLRenderer.rebindPipeline method has been changed slightly. Previously, you had to specify the pipelineInstance, but this is now optional. If you don't, it will use the new previousPipeline property instead. If not set, or none given, it will now return without throwing gl errors as well.
  • If inputWindowEvents is set in the Game Config, then the MouseManager will now listen for the events on window.top instead of just window, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in a try/catch block, as not all sites allow access to window.top (specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow)
  • MouseManager.isTop is a new boolean read-only property that flags if the mouse event listeners were attached to window.top (true), or just window (false). By default Phaser will attempt window.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back to window in those cases and set this property to false (thanks BunBunBun)
  • Types.GameObjects.Text.GetTextSizeObject is a new type def for the GetTextSize function results.
  • Utils.Array.StableSort has been recoded. It's now based on Two-Screens stable sort 0.1.8 and has been updated to fit into Phaser better and no longer create any window bound objects. The inplace function has been removed, just call StableSort(array) directly now. All classes that used StableSort.inplace have been updated to call it directly.
  • If a Scene is paused, or sent to sleep, it will automatically call Keyboard.resetKeys. This means that if you hold a key down, then sleep or pause a Scene, then release the key and resume or wake the Scene, it will no longer think it is still being held down (thanks @samme)
  • Actions.setOrigin will now call updateDisplayOrigin on the items array, otherwise the effects can't be seen when rendering.
  • You can now set the ArcadeWorld.fixedStep property via the ArcadeWorldConfig object (thanks @samme)
  • Utils.Array.NumerArray can now accept the start and end parameters in reverse order, i.e. 10, 1 will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.
  • DataManager.Events.DESTROY is a new event that the Data Manager will listen for from its parent and then call its own destroy method when received.
  • The Quaternion class constructor will now default the values to 0,0,0,1 if they're not provided, making it an identity quaternion, rather than the 0,0,0,0 it was before.
  • You can now set the ParticleEmitter.reserve value via the emitter configuration object (thanks @vforsh)
  • Setting the pixelArt config option will now set antialiasGL to false, as well as antialias. Fix #5309 (thanks @Vegita2)
  • The Shape class now includes the ComputedSize component properties and methods directly in the class, rather than applying as a mixin. setSize is now flagged as being private, because it shouldn't be used on Shape classes, which was leading to confusion as it appeared in the public-facing API. Fix #4811 (thanks @aolsx)
  • The Loader.maxParallelDownloads value is now set to 6 if running on Android, or 32 on any other OS. This avoids net::ERR_FAILED issues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary)
  • WebGLRenderer.defaultScissor is a new property that holds the default scissor dimensions for the renderer. This is modified during resize and avoids continuous array generation in the preRender loop.
  • When running an Arcade Physics overlap test against a StaticBody, it will no longer set the blocked states of the dynamic body. If you are doing a collision test, they will still be set, but they're skipped for overlap-only tests. Fix #4435 (thanks @samme)
  • The Line Game Object will now default its width and height to 1, rather than zero. This allows you to give Line objects a physics body (although you will still need to re-adjust the center of the body manually). Fix #4596 (thanks @andrewaustin)
  • Internally, the Quaternion class now has 4 new private properties: _x, _y, _z and _w and 4 new getters and setters for the public versions. It also now passes most methods via set to allow for the onChange callback to be invoked. This does not change the public-facing API.
  • Group now extends EventEmitter, allowing you to emit custom events from within a Group.
  • Device.Audio.wav now uses audio/wav as the canPlayType check string, instead of audio/wav; codecs="1", which should allow iOS13 to play wav files again.
  • In the Loader.FileTypes.TextFile config you can now override the type and cache destination for the file.
  • Loader.MultiFile will now parse the given files array and only add valid entries into the file list, allowing multifiles to now have optional file entries.

Bug Fixes

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)
  • The GridAlign action didn't work if only the height parameter was set. Fix #5019 (thanks @halilcakar)
  • The Color.HSVToRGB function has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX)
  • Previously, the easeParams array within a Tweens props object, or a multi-object tween, were ignored and it was only used if set on the root Tween object. It will now work correctly set at any depth. Fix #4292 (thanks @willblackmore)
  • When using Camera.setRenderToTexture its zoom and rotation values would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok)
  • GameObjects.Shape.Grid would render a white fill even if you passed undefined as the fill color in the constructor. It now doesn't render cells if no fill color is given.
  • The onMouse events in the Input Manager didn't reset the activePointer property to the mouse, meaning on dual-input systems such as Touch Screen devices, the active pointer would become locked to whichever input method was used first. Fix #4615 #5232 (thanks @mmolina01 @JstnPwll @Legomite)
  • The Scale Managers GetScreenOrientation function will now check for window.orientation first, because iOS mobile browsers have an incomplete implementation of the Screen API, forcing us to use the window value as a priority. This means the Scale Manager will now emit orientationchange events correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu)
  • Time.Clock.addEvent can now take an instance of a TimerEvent as its parameter. Fix #5294 (thanks @samme @EmilSV)
  • GameConfig.audio now defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)
  • The Loader.path was being added to the File URL even if the URL was absolute. This is now checked for and the path is not applied unless the URL is relative (thanks @firesoft)
  • Group.getMatching would always return an empty array. It now returns matching children (thanks @samme)
  • The ParticleManagerWebGLRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in follow offsets separately. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers. Fix #5319 #5195 #4739 #4691 (thanks @vforsh @condeagustin @IvanDem @Formic)
  • The ParticleManagerCanvasRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also uses setToContext internally. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers, or having the Camera zoomed, running under Canvas. Fix #4908 #4531 #4131 (thanks @smjnab @SirLink @jhooper04)
  • The Graphics WebGL Renderer will now default to pathOpen = true. This fixes issues under WebGL where, for example, adding an arc and calling strokePath, without first calling beginPath will no longer cause rendering artefacts when WebGL tries to close the path with a single tri.
  • Graphics.strokeRoundedRect now issues moveTo commands as part of the drawing sequence, preventing issues under WebGL where on older Android devices it would project additional vertices into the display. Fix #3955 (thanks @alexeymolchan)
  • Creating a Bitmap Mask from a texture atlas that was then used to mask another Game Object also using that same texture atlas would throw the error GL_INVALID_OPERATION : glDrawArrays: Source and destination textures of the draw are the same.. It now renders as expected. Fix #4675 (thanks @JacobCaron)
  • When using the same asset for a Game Object to be used as a mask, it would make other Game Objects using the same asset, that appeared above the mask in the display list, to not render. Fix #4767 (thanks @smjnab)
  • When taking a snapshot in WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in the WebGLSnapshot function. Fix #4956 (thanks @gammafp @telinc1)
  • You can now draw a Group to a RenderTexture. Previously, it failed to pass the camera across, resulting in none of the Group children being drawn. Fix #5330 (thanks @somnolik)

Namespace Updates

  • The Phaser.Curves.MoveTo function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.DOM.GetInnerHeight function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Bob class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsManager class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsPlugin class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Particles.EmitterOp class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.GetTextSize function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.MeasureText function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.TextStyle function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Input.CreatePixelPerfectHandler function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapCirc function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapRect function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Tilemap namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Components namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.MatterGameObject class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.PointerConstraint class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetPhysicsPlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetScenePlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Structs.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Tilemaps.Parsers.Tiled function has now been exposed on the Phaser namespace (thanks @samme)
  • Every single Tilemap.Component function has now been made public. This means you can call the Component functions directly, should you need to, outside of the Tilemap system.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360 @volkans80 @jaabberwocky @maikthomas @atursams @LearningCode2023 @DylanC @BenjaminDRichards @rexrainbow @Riderrr @spwilson2 @EmilSV @PhaserEditor2D @Gangryong @vinerz

- JavaScript
Published by photonstorm over 5 years ago

phaser - Phaser v3.50.0 Beta 7

Version 3.50.0 - Subaru - in development

WebGL Pipeline Updates

If you use a custom WebGL Pipeline in your game, you must update your code in order to use Phaser 3.50.

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

Other pipeline changes are as follows:

  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.
  • The WebGLPipeline.shouldFlush method now accepts an optional parameter amount. If given, it will return true if when the amount is added to the vertex count it will exceed the vertex capacity. The Multi Pipeline has been updated to now use this method instead of performing the comparison multiple times itself.

Pipeline Uniform Changes

Piplines now have a new uniforms array that can be passed in with the config. All default pipelines now set these. The array contains the names, as strings, of all uniforms your pipeline shader uses. Once the pipeline shader has been successfully linked, it will use the array of names to look-up the WebGLUniformLocation of all uniforms specified. These are stored in the new WebGLPipeline.uniforms object. This takes place in the new WebGLPipeline.setUniformLocations method.

When a pipeline is bound, you can now use the new methods (listed below) to set uniform values directly on the pipeline. Previously, calling a method such as setFloat3 on a pipeline would pass that call over to WebGLRenderer. The renderer would first check to see if the pipeline program was current, and if not, make it so, before then looking up the uniform location and finally setting it. This is a lot of steps to take for pipelines that potentially need to change uniforms for every Game Object they render.

Under the new methods, and using the new pre-cached uniform locations, these extra steps are skipped. The uniform value is set directly, no shader binding takes place and no location look-up happens. This dramatically reduces the number of WebGL ops being issued per frame. To clearly differentiate these pipline methods, we have renamed them. The new method names are as follows:

  • WebGLPipeline.set1f will set a 1f uniform based on the given name.
  • WebGLPipeline.set2f will set a 2f uniform based on the given name.
  • WebGLPipeline.set3f will set a 3f uniform based on the given name.
  • WebGLPipeline.set4f will set a 4f uniform based on the given name.
  • WebGLPipeline.set1fv will set a 1fv uniform based on the given name.
  • WebGLPipeline.set2fv will set a 2fv uniform based on the given name.
  • WebGLPipeline.set3fv will set a 3fv uniform based on the given name.
  • WebGLPipeline.set4fv will set a 4fv uniform based on the given name.
  • WebGLPipeline.set1iv will set a 1iv uniform based on the given name.
  • WebGLPipeline.set2iv will set a 2iv uniform based on the given name.
  • WebGLPipeline.set3iv will set a 3iv uniform based on the given name.
  • WebGLPipeline.set4iv will set a 4iv uniform based on the given name.
  • WebGLPipeline.set1i will set a 1i uniform based on the given name.
  • WebGLPipeline.set2i will set a 2i uniform based on the given name.
  • WebGLPipeline.set3i will set a 3i uniform based on the given name.
  • WebGLPipeline.set4i will set a 4i uniform based on the given name.
  • WebGLPipeline.setMatrix2fv will set a matrix 2fv uniform based on the given name.
  • WebGLPipeline.setMatrix3fv will set a matrix 3fv uniform based on the given name.
  • WebGLPipeline.setMatrix4fv will set a matrix 4fv uniform based on the given name.

If your code uses any of the old method names, please update them using the list below:

  • WebGLPipeline.setFloat1 has been removed. Please use set1f instead.
  • WebGLPipeline.setFloat2 has been removed. Please use set2f instead.
  • WebGLPipeline.setFloat3 has been removed. Please use set3f instead.
  • WebGLPipeline.setFloat4 has been removed. Please use set4f instead.
  • WebGLPipeline.setFloat1v has been removed. Please use set1fv instead.
  • WebGLPipeline.setFloat2v has been removed. Please use set2fv instead.
  • WebGLPipeline.setFloat3v has been removed. Please use set3fv instead.
  • WebGLPipeline.setFloat4v has been removed. Please use set4fv instead.
  • WebGLPipeline.setInt1 has been removed. Please use set1i instead.
  • WebGLPipeline.setInt2 has been removed. Please use set2i instead.
  • WebGLPipeline.setInt3 has been removed. Please use set3i instead.
  • WebGLPipeline.setInt4 has been removed. Please use set4i instead.
  • WebGLPipeline.setMatrix1 has been removed. Please use setMatrix2fv instead.
  • WebGLPipeline.setMatrix2 has been removed. Please use setMatrix3fv instead.
  • WebGLPipeline.setMatrix3 has been removed. Please use setMatrix4fv instead.

Pipeline Manager

The WebGL.PipelineManager is a new class that is responsbile for managing all of the WebGL Pipelines in Phaser. An instance of the Pipeline Manager is created by the WebGL Renderer and is available under the pipelines property. This means that the WebGL Renderer no longer handles pipelines directly, causing the following API changes:

  • WebGLRenderer.pipelines is no longer a plain object containing pipeline instances. It's now an instance of the PipelineManager class. This instance is created during the init and boot phase of the renderer.
  • The WebGLRenderer.currentPipeline property no longer exists, instead use PipelineManager.current.
  • The WebGLRenderer.previousPipeline property no longer exists, instead use PipelineManager.previous.
  • The WebGLRenderer.hasPipeline method no longer exists, instead use PipelineManager.has.
  • The WebGLRenderer.getPipeline method no longer exists, instead use PipelineManager.get.
  • The WebGLRenderer.removePipeline method no longer exists, instead use PipelineManager.remove.
  • The WebGLRenderer.addPipeline method no longer exists, instead use PipelineManager.add.
  • The WebGLRenderer.setPipeline method no longer exists, instead use PipelineManager.set.
  • The WebGLRenderer.rebindPipeline method no longer exists, instead use PipelineManager.rebind.
  • The WebGLRenderer.clearPipeline method no longer exists, instead use PipelineManager.clear.

The Pipeline Manager also offers the following new features:

  • The PipelineManager.resize method automatically handles resize events across all pipelines.
  • The PipelineManager.preRender method calls the pre-render method of all pipelines.
  • The PipelineManager.render method calls the render method of all pipelines.
  • The PipelineManager.postRender method calls the post-render method of all pipelines.
  • The PipelineManager.setMulti method automatically binds the Multi Texture Pipeline, Phaser's default.
  • The PipelineManager.clear method will clear the pipeline, store it in previous and free the renderer.
  • The PipelineManager.rebind method will reset the rendering context and restore the previous pipeline, if set.

New constants have been created to help you reference a pipeline without needing to use strings:

  • Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE for the Bitmap Mask Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE for the Light 2D Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE for the Single Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE for the Multi Pipeline.
  • Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE for the Rope Pipeline.

All Game Objects have been updated to use the new constants and Pipeline Manager.

Single Pipeline

There is also a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGL Multi-Texture Rendering

The Multi Pipeline (previously called the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw-call bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLPipeline.forceZero is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.

Light Pipeline Changes

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh and Quad Game Objects now support rendering with normal maps.
  • The Graphics Game Objects now support rendering in Light2d. You can even use normal map textures for the texture fills.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • All Shape Game Objects (Rectangle, IsoBox, Star, Polygon, etc) now support rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Both Static and Dynamic Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Lights

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

WebGL ModelViewProjection API Changes

The ModelViewProjection object contained a lot of functions that Phaser never used internally. These have now been moved to external functions, which can be easily excluded from Custom builds to save space.

If you used any of them in your code, please update to the new function names below:

  • Phaser.Renderer.WebGL.MVP is a new namespace under which the Model View Projection functions now live.
  • projIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectIdentity
  • projPersp is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectPerspective
  • modelRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateX
  • modelRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateY
  • modelRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateZ
  • viewLoad is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad
  • viewRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateX
  • viewRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateY
  • viewRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateZ
  • viewScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewScale
  • viewTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewTranslate
  • modelIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Identity
  • modelScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Scale
  • modelTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Translate
  • viewIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewIdentity
  • viewLoad2D is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad2D
  • projOrtho is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectOrtho
  • Phaser.Renderer.WebGL.MVP.SetIdentity is a new function the others use, to save on space.

BitmapText - New Features, Updates and API Changes

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.
  • You can now use setMaxWidth on DynamicBitmapText, which wasn't previously possible. Fix #4997 (thanks @AndreaBoeAbrahamsen)

Update List Changes

The way in which Game Objects add themselves to the Scene Update List has changed. Instead of being added by the Factory methods, they will now add and remove themselves based on the new ADDED_TO_SCENE and REMOVED_FROM_SCENE events. This means, you can now add Sprites directly to a Container, or Group, and they'll animate properly without first having to be part of the Display List. The full set of changes and new features relating to this follow:

  • GameObjects.Events.ADDED_TO_SCENE is a new event, emitted by a Game Object, when it is added to a Scene, or a Container that is part of the Scene.
  • GameObjects.Events.REMOVED_FROM_SCENE is a new event, emitted by a Game Object, when it is removed from a Scene, or a Container that is part of the Scene.
  • Scenes.Events.ADDED_TO_SCENE is a new event, emitted by a Scene, when a new Game Object is added to the display list in the Scene, or a Container that is on the display list.
  • Scenes.Events.REMOVED_FROM_SCENE is a new event, emitted by a Scene, when it a Game Object is removed from the display list in the Scene, or a Container that is on the display list.
  • GameObject.addedToScene is a new method that custom Game Objects can use to perform additional set-up when a Game Object is added to a Scene. For example, Sprite uses this to add itself to the Update List.
  • GameObject.removedFromScene is a new method that custom Game Objects can use to perform additional tear-down when a Game Object is removed from a Scene. For example, Sprite uses this to remove themselves from the Update List.
  • Game Objects no longer automatically remove themselves from the Update List during preDestroy. This should be handled directly in the removedFromScene method now.
  • The Container will now test to see if any Game Object added to it is already on the display list, or not, and emit its ADDED and REMOVED events accordingly. Fix #5267 #3876 (thanks @halgorithm @mbpictures)
  • DisplayList.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • DisplayList.addChildCallback is a new method that overrides the List callback and fires the new ADDED events.
  • DisplayList.removeChildCallback is a new method that overrides the List callback and fires the new REMOVED events.
  • GameObjectCreator.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • GameObjectFactory.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • ProcessQueue.checkQueue is a new boolean property that will make sure only unique objects are added to the Process Queue.
  • The Update List now uses the new checkQueue property to ensure no duplicate objects are on the active list.
  • DOMElementFactory, ExternFactory, ParticleManagerFactor, RopeFactory and SpriteFactory all no longer add the objects to the Update List, this is now handled by the ADDED events instead.
  • Sprite, Rope, ParticleEmitterManager, Extern and DOMElement now all override the addedToScene and removedFromScene callbacks to handle further set-up tasks.

Spine Plugin Updates

  • The Spine Runtimes have been updated to 3.8.99, which are the most recent non-beta versions. Please note, you will need to re-export your animations if you're working in a version of Spine lower than 3.8.20.
  • SpineContainer is a new Game Object available via this.add.spineContainer to which you can add Spine Game Objects only. It uses a special rendering function to retain batching, even across multiple container or Spine Game Object instances, resulting in dramatically improved performance over using regular Containers.
  • A Spine Game Object with setVisible(false) will no longer still cause internal gl commands and is now properly skipped, retaining any current batch in the process. Fix #5174 (thanks @Kitsee)
  • The Spine Game Object WebGL Renderer will no longer clear the type if invisible and will only end the batch if the next type doesn't match.
  • The Spine Game Object WebGL Renderer will no longer rebind the pipeline if it was the final object on the display list, saving lots of gl commands.
  • The Webpack build scripts have all been updated for Webpack 4.44.x. Fix #5243 (thanks @RollinSafary)
  • There is a new npm script npm run plugin.spine.runtimes which will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo into plugins/spine/ in order for this to work and then run npm i.
  • Spine Game Objects can now be rendered to Render Textures. Fix #5184 (thanks @Kitsee)
  • Using > 128 Spine objects in a Container would cause a WebGL: INVALID_OPERATION: vertexAttribPointer: no ARRAY_BUFFER is bound and offset is non-zero error if you added any subsequent Spine objects to the Scene. There is now no limit. Fix #5246 (thanks @d7561985)
  • The Spine Plugin will now work in HEADLESS mode without crashing. Fix #4988 (thanks @raimon-segura)
  • Spine Game Objects now use -1 as their default blend mode, which means 'skip setting it'.
  • The Spine TypeScript defs have been updated for the latest version of the plugin and to add SpineContainers.
  • The SpineGameObject.setAnimation method will now use the trackIndex parameter if ignoreIfPlaying is set and run the check against this track index. Fix #4842 (thanks @vinerz)
  • The SpineFile will no longer throw a warning if adding a texture into the Texture Manager that already exists. This allows you to have multiple Spine JSON use the same texture file, however, it also means you now get no warning if you accidentally load a texture that exists, so be careful with your keys! Fix #4947 (thanks @Nomy1)
  • The Spine Plugin destroy method will now no longer remove the Game Objects from the Game Object Factory, or dispose of the Scene Renderer. This means when a Scene is destroyed, it will keep the Game Objects in the factory for other Scene's to use. Fix #5279 (thanks @Racoonacoon)
  • SpinePlugin.gameDestroy is a new method that is called if the Game instance emits a destroy event. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.
  • SpineFile will now check to see if another identical atlas in the load queue is already loading the texture it needs and will no longer get locked waiting for a file that will never complete. This allows multiple skeleton JSONs to use the same atlas data. Fix #5331 (thanks @Racoonacoon)

Animation API - New Features and Updates

If you use Animations in your game, please read the following important API changes in 3.50:

The Animation API has had a significant overhaul to improve playback handling. Instead of just playing an animation based on its global key, you can now supply a new PlayAnimationConfig object instead, which allows you to override any of the default animation settings, such as duration, delay and yoyo (see below for the full list). This means you no longer have to create lots of duplicate animations just to change properties such as duration, and can now set them dynamically at run-time as well.

  • The Animation class no longer extends EventEmitter, as it no longer emits any events directly. This means you cannot now listen for events directly from an Animation instance. All of the events are now dispatched by the Game Objects instead.
  • All of the SPRITE_ANIMATION_KEY events have been removed. Instead, please use the new events which all carry the frameKey parameter, which can be used to handle frame specific events. The only exception to this is ANIMATION_COMPLETE_KEY, which is a key specific version of the completion event.
  • ANIMATION_UPDATE_EVENT is a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.
  • ANIMATION_STOP_EVENT is a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of the stop methods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)
  • The Game Object Component.Animation component has been renamed to AnimationState and has moved namespace. It's now in Phaser.Animations instead of GameObjects.Components to help differentiate it from the Animation class when browsing the documentation.
  • The play, playReverse, playAfterDelay, playAfterRepeat and chain Sprite and Animation Component methods can now all take a Phaser.Types.Animations.PlayAnimationConfig configuration object, as well as a string, as the key parameter. This allows you to override any default animation setting with those defined in the config, giving you far greater control over animations on a Game Object level, without needing to globally duplicate them.
  • AnimationState.create is a new method that allows you to create animations directly on a Sprite. These are not global and never enter the Animation Manager, instead risiding within the Sprite itself. This allows you to use the same keys across both local and global animations and set-up Sprite specific local animations.
  • All playback methods: play, playReverse, playAfterDelay and playAfterRepeat will now check to see if the given animation key exists locally on the Sprite first. If it does, it's used, otherwise it then checks the global Animation Manager for the key instead.
  • AnimationState.skipMissedFrames is now used when playing an animation, allowing you to create animations that run at frame rates far exceeding the refresh rate, or that will update to the correct frame should the game lag. Feature #4232 (thanks @colorcube)
  • AnimationManager.addMix is a new method that allows you to create mixes 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.
  • AnimationManager.getMix is a new method that will return the mix duration between the two given animations.
  • AnimationManager.removeMix is a new method that will remove the mixture between either two animations, or all mixtures for the given animation.
  • AnimationState.remove is a new method that will remove a locally stored Animation instance from a Sprite.
  • AnimationState.get is a new method that will return a locally stored Animation instance from the Sprite.
  • AnimationState.exists is a new method that will check if a locally stored Animation exists on the Sprite.
  • The internal AnimationState.remove method has been renamed to globalRemove.
  • AnimationState.textureManager is a new property that references the global Texture Manager.
  • AnimationState.anims is a new property that contains locally created Animations in a Custom Map.
  • AnimationState.play and Sprite.play no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • AnimationState.playReverse and Sprite.playReverse no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • The AnimationState.delayedPlay method has been renamed to playAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration.
  • The AnimationState.stopOnRepeat method has been renamed to stopAfterRepeat
  • The AnimationState.getCurrentKey method has been renamed to getName.
  • AnimationState.getFrameName is a new method that will return the key of the current Animation Frame, if an animation has been loaded.
  • AnimationState.playAfterDelay and Sprite.playAfterDelay are new methods that will play the given animation after the delay in ms expires.
  • AnimationState.playAfterRepeat and Sprite.playAfterRepeat are new methods that will play the given animation after the current animation finishes repeating. You can also specify the number of repeats allowed left to run.
  • The AnimationState.chain method is now available on the Sprite class.
  • The AnimationState.stopAfterDelay method is now available on the Sprite class.
  • The AnimationState.stopAfterRepeat method is now available on the Sprite class.
  • The AnimationState.stopOnFrame method is now available on the Sprite class.
  • AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser. Please see the comprehensive documentation for this method for full details on how to do this.
  • AnimationState now handles all of the loading of the animation. It no longer has to make calls out to the Animation Manager or Animation instance itself and will load the animation data directly, replacing as required from the optional PlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.
  • The PlayAnimationConfig.frameRate property lets you optionally override the animation frame rate.
  • The PlayAnimationConfig.duration property lets you optionally override the animation duration.
  • The PlayAnimationConfig.delay property lets you optionally override the animation delay.
  • The PlayAnimationConfig.repeat property lets you optionally override the animation repeat counter.
  • The PlayAnimationConfig.repeatDelay property lets you optionally override the animation repeat delay value.
  • The PlayAnimationConfig.yoyo property lets you optionally override the animation yoyo boolean.
  • The PlayAnimationConfig.showOnStart property lets you optionally override the animation show on start value.
  • The PlayAnimationConfig.hideOnComplete property lets you optionally override the animation hide on complete value.
  • The PlayAnimationConfig.startFrame property lets you optionally set the animation frame to start on.
  • The PlayAnimationConfig.timeScale property lets you optionally set the animation time scale factor.
  • AnimationState.delayCounter is a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animation START events fire. Fix #4426 (thanks @bdaenen)
  • AnimationState.hasStarted is a new boolean property that allows you to tell if the current animation has started playing, or is still waiting for a delay to expire.
  • AnimationState.showOnStart is a new boolean property that controls if the Game Object should have setVisible(true) called on it when the animation starts.
  • AnimationState.hideOnComplete is a new boolean property that controls if the Game Object should have setVisible(false) called on it when the animation completes.
  • The AnimationState.chain method docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does!
  • The AnimationState.setDelay method has been removed. It never actually worked and you can now perform the same thing by calling either playAfterDelay or setting the delay property in the play config.
  • The AnimationState.getDelay method has been removed. You can now read the delay property directly.
  • The AnimationState.setRepeat method has been removed. You can achieve the same thing by setting the repeat property in the play config, or adjusting the public repeatCounter property if the animation has started.
  • AnimationState.handleStart is a new internal private method that handles the animation start process.
  • AnimationState.handleRepeat is a new internal private method that handles the animation repeat process.
  • AnimationState.handleStop is a new internal private method that handles the animation stop process.
  • AnimationState.handleComplete is a new internal private method that handles the animation complete process.
  • AnimationState.emitEvents is a new internal private method that emits animation events, cutting down on duplicate code.
  • The AnimationState.restart method has a new optional boolean parameter resetRepeats which controls if you want to reset the repeat counter during the restart, or not.
  • Animation.getTotalFrames is a new method that will return the total number of frames in the animation. You can access it via this.anims.currentAnim.getTotalFrames from a Sprite.
  • Animation.calculateDuration is a new method that calculates the duration, frameRate and msPerFrame for a given animation target.
  • The BuildGameObjectAnimation function now uses the PlayAnimationConfig object to set the values.
  • Sprite.playReverse is a new method that allows you to play the given animation in reverse on the Sprite.
  • Sprite.playAfterDelay is a new method that allows you to play the given animation on the Sprite after a delay.
  • Sprite.stop is a new method that allows you to stop the current animation on the Sprite.
  • AnimationManager.load has been removed as it's no longer required.
  • AnimationManager.staggerPlay has been fixed so you can now pass in negative stagger values.
  • AnimationManager.staggerPlay has a new optional boolean parameter staggerFirst, which allows you to either include or exclude the first child in the stagger calculations.
  • The Animation.completeAnimation method has been removed as it's no longer required.
  • The Animation.load method has been removed as it's no longer required.
  • The Animation.setFrame method has been removed as it's no longer required.
  • The Animation.getFirstTick method has no longer needs the includeDelay parameter, as it's handled by AnimationState now.
  • The Animation.getFrames method has a new optional boolean parameter sortFrames which will run a numeric sort on the frame names after constructing them, if a string-based frame is given.
  • Types.Animations.Animation has a new boolean property sortFrames, which lets Phaser numerically sort the generated frames.
  • AnimationState.timeScale is a new public property that replaces the old private _timeScale property.
  • AnimationState.delay is a new public property that replaces the old private _delay property.
  • AnimationState.repeat is a new public property that replaces the old private _repeat property.
  • AnimationState.repeatDelay is a new public property that replaces the old private _repeatDelay property.
  • AnimationState.yoyo is a new public property that replaces the old private _yoyo property.
  • AnimationState.inReverse is a new public property that replaces the old private _reverse property.
  • AnimationState.startAnimation is a new public method that replaces the old private _startAnimation method.
  • The AnimationState.getProgress method has been fixed so it will return correctly if the animation is playing in reverse.
  • The AnimationState.globalRemove method will now always be called when an animation is removed from the global Animation Manager, not just once.
  • The AnimationState.getRepeat method has now been removed. You can get the value from the repeat property.
  • The AnimationState.setRepeatDelay method has now been removed. You can set the value using the repeatDelay config property, or changing it at run-time.
  • AnimationState.complete is a new method that handles the completion in animation playback.
  • The AnimationState.setTimeScale method has now been removed. You can set the value using the timeScale config property, or changing it at run-time.
  • The AnimationState.getTimeScale method has now been removed. You can read the value using the timeScale property.
  • The AnimationState.getTotalFrames method has been fixed and won't error if called when no animation is loaded.
  • The AnimationState.setYoyo method has now been removed. You can set the value using the yoyo config property, or changing it at run-time.
  • The AnimationState.getYoyo method has now been removed. You can read the value using the yoyo property.
  • The AnimationState.stopAfterRepeat method now has an optional parameter repeatCount, so you can tell the animation to stop after a specified number of repeats, not just 1.
  • When playing an animation in reverse, if it reached the first frame and had to repeat, it would then jump to the frame before the final frame and carry on, skipping out the final frame.
  • The AnimationState.updateFrame method has now been removed. Everything is handled by setCurrentFrame instead, which removes one extra step out of the update process.
  • GenerateFrameNames will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers would include the __BASE frame by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.
  • GenerateFrameNumbers can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.
  • GenerateFrameNames can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.

Mesh Game Object - New Features, Updates and API Changes

// TODO // Include RGB class

Input / Mouse Updates and API Changes

  • ScaleManager.refresh is now called when the Game.READY event fires. This fixes a bug where the Scale Manager would have the incorrect canvas bounds, because they were calculated before a previous canvas was removed from the DOM. Fix #4862 (thanks @dranitski)
  • The Game Config property inputMouseCapture has been removed, as this is now split into 3 new config options:
  • inputMousePreventDefaultDown is a new config option that allows you to control preventDefault calls specifically on mouse down events. Set it via input.mouse.preventDefaultDown in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultUp is a new config option that allows you to control preventDefault calls specifically on mouse up events. Set it via input.mouse.preventDefaultUp in the Game Config. It defaults to true, the same as the previous capture property did.
  • inputMousePreventDefaultMove is a new config option that allows you to control preventDefault calls specifically on mouse move events. Set it via input.mouse.preventDefaultMove in the Game Config. It defaults to true, the same as the previous capture property did.
  • The MouseManager.capture property has been removed, as this is now split into 3 new config options (see below)
  • MouseManager.preventDefaultDown is a new boolean property, set via the inputMousePreventDefaultDown config option that allows you to toggle capture of mouse down events at runtime.
  • MouseManager.preventDefaultUp is a new boolean property, set via the inputMousePreventDefaultUp config option that allows you to toggle capture of mouse up events at runtime.
  • MouseManager.preventDefaultMove is a new boolean property, set via the inputMousePreventDefaultMove config option that allows you to toggle capture of mouse move events at runtime.
  • In the MouseManager the up, down and move events are no longer set as being passive if captured. Over, Out, Wheel and the Window level Down and Up events are always flagged as being passive.
  • The GamepadPlugin will now call refreshPads as part of its start process. This allows you to use Gamepads across multiple Scenes, without having to wait for a connected event from each one of them. If you've already had a connected event in a previous Scene, you can now just read the pads directly via this.input.gamepad.pad1 and similar. Fix #4890 (thanks @Sytten)
  • Shutting down the Gamepad plugin (such as when sleeping a Scene) no longer calls GamepadPlugin.disconnectAll, but destroying it does.
  • Gamepad._created is a new private internal property that keeps track of when the instance was created. This is compared to the navigator timestamp in the update loop to avoid event spamming. Fix #4890.
  • Pointer.down will now check if the browser is running under macOS and if the ctrl key was also pressed, if so, it will flag the down event as being a right-click instead of a left-click, as per macOS conventions. Fix #4245 (thanks @BigZaphod)
  • When destroying an interactive Game Object that had useHandCursor enabled, it would reset the CSS cursor to default, even if the cursor wasn't over that Game Object. It will now only reset the cursor if it's over the Game Object being destroyed. Fix #5321 (thanks @JstnPwll)
  • The InputPlugin.shutdown method will now reset the CSS cursor, in case it was set by any Game Objects in the Scene that have since been destroyed.

Tint Updates and Shader Changes

Phaser has had the ability to apply an additive tint to a Game Object since the beginning, and gained 'filled tints', with and without texture alpha, in v3.11. While this was handy, it introduced a 3-way if-else condition to the shaders to handle the different modes. Plus, setting tint colors was also generating rgb order Float32 color values for each Game Object, making reading those colors back again difficult (as they'd return in BGR order).

This has all changed in 3.50, as outlined below. Tint values are now used directly in the shader and don't pass through a color conversion function first. Lots of private properties have been removed and the shaders no longer have a 3-way if-else block. All of this means improved performance and a slight reduction in memory overhead.

  • Tint.tintTopLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTL which has now been removed.
  • Tint.tintTopRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintTR which has now been removed.
  • Tint.tintBottomLeft is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBL which has now been removed.
  • Tint.tintBottomRight is now a normal property in RGB order, not a setter, and no longer passes through the GetColorFromValue function. This directly replaces the private property _tintBR which has now been removed.
  • The property Tint._isTinted has been removed as it's no longer required.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they now read the color value as outTint.bgr instead of outTint.rgb. This allows the colors to remain in RGB order within the Tint component.
  • The Single.frag, Light.frag and Multi.frag shaders have all been updated so they no longer have a 3-way check on the outTintEffect value.
  • The Multi Pipeline, Bitmap Text, Render Texture, Text, TileSprite and Camera now all read the tint values from the public properties instead of the private _tintTL etc ones. They also now set the tintEffect value directly from the tintFill property, removing another conditional check.
  • The function GetColorFromValue has been removed as it's no longer used internally.
  • The Rope.tintFill property is now a boolean, not an integer, and can no longer take 2 as a value for a complete fill. Instead, you should provide a solid color texture with no alpha.
  • As a result of the change to the shader, all uses of the WebGL Util function getTintAppendFloatAlphaAndSwap have been replaced with getTintAppendFloatAlpha instead.
  • As a result of the change to the shader, the Multi Pipeline now uses the WebGLRenderer.whiteTexture and tintEffect mode of 1 by default, instead of mode 2 (which has been removed) and a transparent texture. This ensures Graphics and Shapes objects still render correctly under the new smaller shader code.
  • WebGLRenderer.whiteTexture is a new property that is a reference to a pure white 4x4 texture that is created during Boot by the Texture Manager. The Multi Pipeline uses this internally for all Graphic, Shape and fill rendering.
  • The TextureManager now generates a new texture with the key __WHITE durings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines.
  • Config.images.white is a new Game Config property that specifies the 4x4 white PNG texture used by Graphics rendering. You can override this via the config, but only do so if needed.

Arcade Physics Updates

Prior to v3.50 an Arcade Physics Body could be one of two states: immovable, or moveable. An immovable body could not receive any impact from another Body. If something collided with it, it wouldn't even separate to break free from the collision (the other body had to take the full separation value). It was intended for objects such as platforms, ground or walls, there they absolutely shouldn't move under any circumstances. As a result, two immovable bodies could never be collided together. While this worked for scenery-like items, it didn't work if you required maybe 2 players who could collide with each other, but should never be able to push one another. As of 3.50 all physics bodies now have a new property pushable that allows this. A pushable body can share separation with its collider, as well as take on mass-based velocity from the impact. A non-pushable body will behave differently depending on what it collides with. For example, a pushable body hitting a non-pushable (or immoveable) body will rebound off it.

  • The Arcade Physics Body class has a new boolean property pushable (true, by default). This allows you to set if a Body can be physically pushed by another Body, or not. Fix #4175 #4415 (thanks @inmylo @CipSoft-Components)
  • Body.setPushable is a new chainable method that allows you to set the pushable state of a Body.
  • Arcade.Components.Pushable is a new component, inherited by the standard Arcade Physics Image and Sprite classes.
  • Bodies will now check to see if they are blocked in the direction they're being pushed, before resolving the collision. This helps stop some bodies from being pushed into other objects.
  • Bodies will now check which direction they were moving and separate accordingly. This helps stop some bodies from being pushed into other objects.
  • ArcadePhysics.disableUpdate is a new method that will prevent the Arcade Physics World update method from being called when the Scene updates. By disabling it, you're free to call the update method yourself, passing in your own delta and time values.
  • ArcadePhysics.enableUpdate is a new method that will make the Arcade Physics World update in time with the Scene update. This is the default, so only call this if you have specifically disabled it previously.
  • ArcadeWorldConfig.customUpdate is a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. If true the World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)
  • Physics.Arcade.Body.setCollideWorldBounds now has a new optional parameter onWorldBounds which allows you to enable the Body's onWorldBounds property in the same call (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityX is a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)
  • ArcadePhysics.Body.setMaxVelocityY is a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)
  • The PhysicsGroup config now has two new optional properties maxVelocityX and maxVelocityY which allows you to set the maximum velocity on bodies added to the Group (thanks @samme)
  • The Arcade.Body.resetFlags method has a new optional boolean parameter clear. If set, it clears the wasTouching flags on the Body. This happens automatically when Body.reset is called. Previous to this, the flags were not reset until the next physics step (thanks @samme)
  • Physics.Arcade.ProcessX is a new set of functions, called by the SeparateX function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.
  • Physics.Arcade.ProcessY is a new set of functions, called by the SeparateY function, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.

Loader Cache Changes

When loading any of the file types listed below it will no longer store the data file in the cache. For example, when loading a Texture Atlas using a JSON File, it would store the parsed image data in the Texture Manager and also store the JSON in the JSON Cache under the same key. This has changed in 3.50. The data files are no longer cached, as they are not required by the textures once parsing is completed, which happens during load. This helps free-up memory (how much depends on the size of your data files) and also allows you to easily remove textures based on just their key, without also having to clear out the corresponding data cache.

  • AtlasJSONFile no longer stores the JSON in the JSON Cache once the texture has been created.
  • AtlasXMLFile no longer stores the XML in the XML Cache once the texture has been created.
  • UnityAtlasFile no longer stores the Text in the Text Cache once the texture has been created.
  • BitmapFontFile no longer stores the XML in the XML Cache once the texture has been created.
  • You can now use TextureManager.remove to remove a texture and not have to worry about clearing the corresponding JSON or XML cache entry as well in order to reload a new texture using the same key. Fix #5323 (thanks @TedGriggs)

Removal of 'resolution' property from across the API

For legacy reasons, Phaser 3 has never properly supported HighDPI devices. It will render happily to them of course, but wouldn't let you set a 'resolution' for the Canvas beyond 1. Earlier versions of 3.x had a resolution property in the Game Config, but it was never fully implemented (for example, it would break zooming cameras). When the Scale Manager was introduced in v3.16 we forced the resolution to be 1 to avoid it breaking anything else internally.

For a long time, the 'resolution' property has been present - taunting developers and confusing new comers. In this release we have finally gone through and removed all references to it. The Game Config option is now gone, it's removed from the Scale Manager, Base Camera and everywhere else where it matters. As much as we would have liked to implement the feature, we've spent too long without it, and things have been built around the assumption it isn't present. The API just wouldn't cope with having it shoe-horned in at this stage. As frustrating as this is, it's even more annoying to just leave the property there confusing people and wasting CPU cycles. Phaser 4 has been built with HighDPI screens in mind from the very start, but it's too late for v3. The following changes are a result of this removal:

  • The Phaser.Scale.Events#RESIZE event no longer sends the resolution as a parameter.
  • The BaseCamera.resolution property has been removed.
  • The internal private BaseCamera._cx, _cy, _cw and _ch properties has been removed, use x, y, width and height instead.
  • The BaseCamera.preRender method no longer receives or uses the resolution parameter.
  • The Camera.preRender method no longer receives or uses the resolution parameter.
  • The CameraManager.onResize method no longer receives or uses the resolution parameter.
  • The Core.Config.resolution property has been removed.
  • The TextStyle.resolution property is no longer read from the Game Config. You can still set it via the Text Style config to a value other than 1, but it will default to this now.
  • The CanvasRenderer no longer reads or uses the Game Config resolution property.
  • The PipelineManager.resize method along with WebGLPipeline.resize and anything else that extends them no longer receives or uses the resolution parameter.
  • The WebGLRenderer.resize and onResize methods no longer receives or uses the resolution parameter.
  • The ScaleManager.resolution property has been removed and all internal use of it.

Removed 'interpolationPercentage' parameter from all render functions

Since v3.0.0 the Game Object render functions have received a parameter called interpolationPercentage that was never used. The renderers do not calculate this value and no Game Objects apply it, so for the sake of clairty, reducing code and removing complexity from the API it has been removed from every single function that either sent or expected the parameter. This touches every single Game Object and changes the parameter order as a result, so please be aware of this if you have your own custom Game Objects, or plugins, that implement their own render methods. In terms of surface API changes, you shouldn't notice anything at all from this removal.

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • WebGLRenderer.setInt1iv will allow you to look-up and set a 1iv uniform on the given shader.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.
  • You can now use this.renderer from within a Scene, as it's now a Scene-level property and part of the Injection Map.
  • Clock.addEvent can now take an existing TimerEvent object, as well as a config object. If a TimerEvent is given it will be removed from the Clock, reset and then added. This allows you to pool TimerEvents rather than constantly create and delete them. Fix #4115 (thanks @jcyuan)
  • Clock.removeEvent is a new method that allows you to remove a TimerEvent, or an array of them, from all internal lists of the current Clock.
  • Group.getMatching is a new method that will return any members of the Group that match the given criteria, such as getMatching('visible', true) (thanks @atursams)
  • Utils.Array.SortByDigits is a new function that takes the given array of strings and runs a numeric sort on it, ignoring any non-digits.
  • GroupCreateConfig, which is used when calling Group.createMultiple or Group.createFromConfig, can now accept the following new properties: setOrigin: { x, y, stepX, stepY } which are applied to the items created by the Group.
  • Transform.copyPosition is a new method that will copy the position from the given object to the Game Object (thanks @samme)
  • The Text.MeasureText function, which is used to calculate the ascent and descent of Text Game Objects whenever the style, or font size, is changed, has been updated to use the new actualBoundingBoxAscent functions present in modern browsers. This allows for significantly faster ascent calculations than previously. Older browsers, such as IE, will still fall back (thanks @rexrainbow)
  • GameObjects.GetCalcMatrix is a new function that is used to calculate the transformed Game Object matrix, based on the given Game Object, Camera and Parent. This function is now used by the following Game Objects: BitmapText (Static and Dynamic), Graphics, Extern, Mesh, Rope, Shader, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. This dramatically reduces the amount of duplicate code across the API.
  • Utils.Array.Matrix.Translate is a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.
  • Vertor3.addScale is a new method that will add the given vector and multiply it in the process.
  • When defining the ease used with a Particle Emitter you can now set easeParams in the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh)
  • BitmapMask.createMask is a new method that will internally create the WebGL textures and framebuffers required for the mask. This is now used by the constructor and if the context is lost. It now also clears any previous textures/fbos that may have been created first, helping prevent memory leaks.
  • BitmapMask.clearMask will delete any WebGL textures or framebuffers the mask is using. This is now called when the mask is destroyed, or a new mask is created upon it.
  • Quaternion now has a new property onChangeCallback which, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.
  • The Quaternion.set method has a new optional boolean parameter update (defaults to true), which will call the onChangeCallback if set.
  • Quaternion.setFromEuler is a new method that will set the quaternion from the given Euler object, optionally calling the onChangeCallback in the process.
  • Quaternion.setFromRotationMatrix is a new method that will set the rotation of the quaternion from the given Matrix4.
  • Vector3.setFromMatrixPosition is a new method that will set the components of the Vector3 based on the position of the given Matrix4.
  • Vector3.setFromMatrixColumn is a new method that will set the components of the Vector3 based on the specified Matrix4 column.
  • Vector3.fromArray is a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.
  • Vector3.min is a new method that will set the components of the Vector3 based on the Main.min between it and the given Vector3.
  • Vector3.max is a new method that will set the components of the Vector3 based on the Main.max between it and the given Vector3.
  • Vector3.addVectors is a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.
  • Vector3.addScalar is a new method that will multiply the components of the Vector3 by the scale value given.
  • Vector3.applyMatrix3 is a new method that will take a Matrix3 and apply it to the Vector3.
  • Vector3.applyMatrix4 is a new method that will take a Matrix4 and apply it to the Vector3.
  • Vector3.projectViewMatrix is a new method that multiplies the Vector3 by the given view and projection matrices.
  • Vector3.unprojectViewMatrix is a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.
  • Matrix4.getMaxScaleOnAxis is a new method that will return the maximum axis scale from the Matrix4.
  • Matrix4.lookAtRH is a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.
  • Matrix4.transform is a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.
  • Matrix4.multiplyMatrices is a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.
  • Matrix4.premultiply is a new method that takes a Matrix4 and multiplies it by the current Matrix4.
  • Matrix4.getInverse is a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.
  • WebGLRenderer.instancedArraysExtension is a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.
  • WebGLRenderer.vaoExtension is a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Earcut has now been exposed and is available via Geom.Polygon.Earcut and is fully documented.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • The TextureTintStripPipeline now extends TextureTintPipeline and just changes the topolgy, vastly reducing the filesize.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.
  • global.Phaser = Phaser has been removed, as it's no longer required by the UMD loader, which should make importing in Angular 10 easier. Fix #5212 (thanks @blackyale)
  • Pointer.downTime now stores the event timestamp of when the first button on the input device was pressed down, not just when button 1 was pressed down.
  • Pointer.upTime now stores the event timestamp of when the final depressed button on the input device was released, not just when button 1 was released.
  • The Pointer.getDuration method now uses the new Pointer downTime and upTime values, meaning it will accurately report the duration of when any button is being held down, not just the primary one. Fix #5112 (thanks @veleek)
  • The BaseShader default vertex shader now includes the outTexCoord vec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok)
  • When using the GameObjectCreator for Containers you can now specify the children property in the configuration object.
  • WebGLRenderer.finalType is a new boolean property that signifies if the current Game Object being rendered is the final one in the list.
  • The WebGLRenderer.updateCanvasTexture method will now set gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL to true, which should stop issues where you update a Text Game Object, having added a Render Texture or Spine Game Object to the Scene after it, which switches the PMA setting. Fix #5064 #5155 (thanks @hugoruscitti @immangrove-supertree)
  • Textures.Parsers.JSONHash will now perform a hasOwnProperty check when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes from JSON.parse. Fix #4768 (thanks @RollinSafary)
  • The Camera3D Plugin has been rebuilt for Phaser 3.50 and the webpack config updated. This plugin is now considered deprecated and will not be updated beyond this release.
  • Tween.seek will no longer issue a console warning for 'Tween.seek duration too long', it's now up to you to check on the performance of tween seeking.
  • WebGLRenderer.previousPipeline is a new property that is set during a call to clearPipeline and used during calls to rebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.
  • The WebGLRenderer.rebindPipeline method has been changed slightly. Previously, you had to specify the pipelineInstance, but this is now optional. If you don't, it will use the new previousPipeline property instead. If not set, or none given, it will now return without throwing gl errors as well.
  • If inputWindowEvents is set in the Game Config, then the MouseManager will now listen for the events on window.top instead of just window, which should help in situations where the pointer is released outside of an embedded iframe. Fix #4824 (thanks @rexrainbow)
  • Types.GameObjects.Text.GetTextSizeObject is a new type def for the GetTextSize function results.
  • Utils.Array.StableSort has been recoded. It's now based on Two-Screens stable sort 0.1.8 and has been updated to fit into Phaser better and no longer create any window bound objects. The inplace function has been removed, just call StableSort(array) directly now. All classes that used StableSort.inplace have been updated to call it directly.
  • If a Scene is paused, or sent to sleep, it will automatically call Keyboard.resetKeys. This means that if you hold a key down, then sleep or pause a Scene, then release the key and resume or wake the Scene, it will no longer think it is still being held down (thanks @samme)
  • Actions.setOrigin will now call updateDisplayOrigin on the items array, otherwise the effects can't be seen when rendering.
  • You can now set the ArcadeWorld.fixedStep property via the ArcadeWorldConfig object (thanks @samme)
  • Utils.Array.NumerArray can now accept the start and end parameters in reverse order, i.e. 10, 1 will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.
  • DataManager.Events.DESTROY is a new event that the Data Manager will listen for from its parent and then call its own destroy method when received.
  • The Quaternion class constructor will now default the values to 0,0,0,1 if they're not provided, making it an identity quaternion, rather than the 0,0,0,0 it was before.
  • You can now set the ParticleEmitter.reserve value via the emitter configuration object (thanks @vforsh)
  • Setting the pixelArt config option will now set antialiasGL to false, as well as antialias. Fix #5309 (thanks @Vegita2)
  • The Shape class now includes the ComputedSize component properties and methods directly in the class, rather than applying as a mixin. setSize is now flagged as being private, because it shouldn't be used on Shape classes, which was leading to confusion as it appeared in the public-facing API. Fix #4811 (thanks @aolsx)
  • The Loader.maxParallelDownloads value is now set to 6 if running on Android, or 32 on any other OS. This avoids net::ERR_FAILED issues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary)
  • WebGLRenderer.defaultScissor is a new property that holds the default scissor dimensions for the renderer. This is modified during resize and avoids continuous array generation in the preRender loop.
  • When running an Arcade Physics overlap test against a StaticBody, it will no longer set the blocked states of the dynamic body. If you are doing a collision test, they will still be set, but they're skipped for overlap-only tests. Fix #4435 (thanks @samme)
  • The Line Game Object will now default its width and height to 1, rather than zero. This allows you to give Line objects a physics body (although you will still need to re-adjust the center of the body manually). Fix #4596 (thanks @andrewaustin)
  • Internally, the Quaternion class now has 4 new private properties: _x, _y, _z and _w and 4 new getters and setters for the public versions. It also now passes most methods via set to allow for the onChange callback to be invoked. This does not change the public-facing API.

Bug Fixes

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)
  • The GridAlign action didn't work if only the height parameter was set. Fix #5019 (thanks @halilcakar)
  • The Color.HSVToRGB function has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX)
  • Previously, the easeParams array within a Tweens props object, or a multi-object tween, were ignored and it was only used if set on the root Tween object. It will now work correctly set at any depth. Fix #4292 (thanks @willblackmore)
  • When using Camera.setRenderToTexture its zoom and rotation values would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok)
  • GameObjects.Shape.Grid would render a white fill even if you passed undefined as the fill color in the constructor. It now doesn't render cells if no fill color is given.
  • The onMouse events in the Input Manager didn't reset the activePointer property to the mouse, meaning on dual-input systems such as Touch Screen devices, the active pointer would become locked to whichever input method was used first. Fix #4615 #5232 (thanks @mmolina01 @JstnPwll @Legomite)
  • The Scale Managers GetScreenOrientation function will now check for window.orientation first, because iOS mobile browsers have an incomplete implementation of the Screen API, forcing us to use the window value as a priority. This means the Scale Manager will now emit orientationchange events correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu)
  • Time.Clock.addEvent can now take an instance of a TimerEvent as its parameter. Fix #5294 (thanks @samme @EmilSV)
  • GameConfig.audio now defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)
  • The Loader.path was being added to the File URL even if the URL was absolute. This is now checked for and the path is not applied unless the URL is relative (thanks @firesoft)
  • Group.getMatching would always return an empty array. It now returns matching children (thanks @samme)
  • The ParticleManagerWebGLRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in follow offsets separately. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers. Fix #5319 #5195 #4739 #4691 (thanks @vforsh @condeagustin @IvanDem @Formic)
  • The ParticleManagerCanvasRenderer now calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also uses setToContext internally. This fixes numerous issues with particle emitters being incorrectly offset when added to Containers, or having the Camera zoomed, running under Canvas. Fix #4908 #4531 #4131 (thanks @smjnab @SirLink @jhooper04)
  • The Graphics WebGL Renderer will now default to pathOpen = true. This fixes issues under WebGL where, for example, adding an arc and calling strokePath, without first calling beginPath will no longer cause rendering artefacts when WebGL tries to close the path with a single tri.
  • Graphics.strokeRoundedRect now issues moveTo commands as part of the drawing sequence, preventing issues under WebGL where on older Android devices it would project additional vertices into the display. Fix #3955 (thanks @alexeymolchan)
  • Creating a Bitmap Mask from a texture atlas that was then used to mask another Game Object also using that same texture atlas would throw the error GL_INVALID_OPERATION : glDrawArrays: Source and destination textures of the draw are the same.. It now renders as expected. Fix #4675 (thanks @JacobCaron)
  • When using the same asset for a Game Object to be used as a mask, it would make other Game Objects using the same asset, that appeared above the mask in the display list, to not render. Fix #4767 (thanks @smjnab)
  • When taking a snapshot in WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in the WebGLSnapshot function. Fix #4956 (thanks @gammafp @telinc1)
  • You can now draw a Group to a RenderTexture. Previously, it failed to pass the camera across, resulting in none of the Group children being drawn. Fix #5330 (thanks @somnolik)

Namespace Updates

  • The Phaser.Curves.MoveTo function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.DOM.GetInnerHeight function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Bob class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsManager class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsPlugin class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Particles.EmitterOp class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.GetTextSize function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.MeasureText function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.TextStyle function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Input.CreatePixelPerfectHandler function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapCirc function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapRect function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Tilemap namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Components namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.MatterGameObject class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.PointerConstraint class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetPhysicsPlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetScenePlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Structs.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Tilemaps.Parsers.Tiled function has now been exposed on the Phaser namespace (thanks @samme)
  • Every single Tilemap.Component function has now been made public. This means you can call the Component functions directly, should you need to, outside of the Tilemap system.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360 @volkans80 @jaabberwocky @maikthomas @atursams @LearningCode2023 @DylanC @BenjaminDRichards @rexrainbow @Riderrr @spwilson2 @EmilSV @PhaserEditor2D @Gangryong @vinerz

- JavaScript
Published by photonstorm over 5 years ago

phaser - Phaser v3.50.0 Beta 4

WebGL Pipeline Updates

If you use a custom WebGL Pipeline in your game, you must update your code in order to use Phaser 3.50.

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

Other pipeline changes are as follows:

  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.

Single Pipeline

There is also a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGL Multi-Texture Rendering

The Multi Pipeline (previously the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw-call bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLPipeline.forceZero is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.

Light Pipeline Changes

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh and Quad Game Objects now support rendering with normal maps.
  • The Graphics Game Objects now support rendering in Light2d. You can even use normal map textures for the texture fills.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • All Shape Game Objects (Rectangle, IsoBox, Star, Polygon, etc) now support rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Both Static and Dynamic Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Lights

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

WebGL ModelViewProjection API Changes

The ModelViewProjection object contained a lot of functions that Phaser never used internally. These have now been moved to external functions, which can be easily excluded from Custom builds to save space.

If you used any of them in your code, please update to the new function names below:

  • Phaser.Renderer.WebGL.MVP is a new namespace under which the Model View Projection functions now live.
  • projIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectIdentity
  • projPersp is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectPerspective
  • modelRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateX
  • modelRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateY
  • modelRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateZ
  • viewLoad is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad
  • viewRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateX
  • viewRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateY
  • viewRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateZ
  • viewScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewScale
  • viewTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewTranslate
  • modelIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Identity
  • modelScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Scale
  • modelTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Translate
  • viewIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewIdentity
  • viewLoad2D is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad2D
  • projOrtho is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectOrtho
  • Phaser.Renderer.WebGL.MVP.SetIdentity is a new function the others use, to save on space.

BitmapText New Features, Updates and API Changes

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.

Update List Changes

The way in which Game Objects add themselves to the Scene Update List has changed. Instead of being added by the Factory methods, they will now add and remove themselves based on the new ADDED_TO_SCENE and REMOVED_FROM_SCENE events. This means, you can now add Sprites directly to a Container, or Group, and they'll animate properly without first having to be part of the Display List. The full set of changes and new features relating to this follow:

  • GameObjects.Events.ADDED_TO_SCENE is a new event, emitted by a Game Object, when it is added to a Scene, or a Container that is part of the Scene.
  • GameObjects.Events.REMOVED_FROM_SCENE is a new event, emitted by a Game Object, when it is removed from a Scene, or a Container that is part of the Scene.
  • Scenes.Events.ADDED_TO_SCENE is a new event, emitted by a Scene, when a new Game Object is added to the display list in the Scene, or a Container that is on the display list.
  • Scenes.Events.REMOVED_FROM_SCENE is a new event, emitted by a Scene, when it a Game Object is removed from the display list in the Scene, or a Container that is on the display list.
  • GameObject.addedToScene is a new method that custom Game Objects can use to perform additional set-up when a Game Object is added to a Scene. For example, Sprite uses this to add itself to the Update List.
  • GameObject.removedFromScene is a new method that custom Game Objects can use to perform additional tear-down when a Game Object is removed from a Scene. For example, Sprite uses this to remove themselves from the Update List.
  • Game Objects no longer automatically remove themselves from the Update List during preDestroy. This should be handled directly in the removedFromScene method now.
  • The Container will now test to see if any Game Object added to it is already on the display list, or not, and emit its ADDED and REMOVED events accordingly. Fix #5267 #3876 (thanks @halgorithm @mbpictures)
  • DisplayList.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • DisplayList.addChildCallback is a new method that overrides the List callback and fires the new ADDED events.
  • DisplayList.removeChildCallback is a new method that overrides the List callback and fires the new REMOVED events.
  • GameObjectCreator.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • GameObjectFactory.events is a new property that references the Scene's Event Emitter. This is now used internally.
  • ProcessQueue.checkQueue is a new boolean property that will make sure only unique objects are added to the Process Queue.
  • The Update List now uses the new checkQueue property to ensure no duplicate objects are on the active list.
  • DOMElementFactory, ExternFactory, ParticleManagerFactor, RopeFactory and SpriteFactory all no longer add the objects to the Update List, this is now handled by the ADDED events instead.
  • Sprite, Rope, ParticleEmitterManager, Extern and DOMElement now all override the addedToScene and removedFromScene callbacks to handle further set-up tasks.

Spine Plugin Updates

  • The Spine Runtimes have been updated to 3.8.95, which are the most recent non-beta versions. Please note, you will need to re-export your animations if you're working in a version of Spine lower than 3.8.20.
  • SpineContainer is a new Game Object available via this.add.spineContainer to which you can add Spine Game Objects only. It uses a special rendering function to retain batching, even across multiple container or Spine Game Object instances, resulting in dramatically improved performance over using regular Containers.
  • A Spine Game Object with setVisible(false) will no longer still cause internal gl commands and is now properly skipped, retaining any current batch in the process. Fix #5174 (thanks @Kitsee)
  • The Spine Game Object WebGL Renderer will no longer clear the type if invisible and will only end the batch if the next type doesn't match.
  • The Spine Game Object WebGL Renderer will no longer rebind the pipeline if it was the final object on the display list, saving lots of gl commands.
  • The Webpack build scripts have all been updated for Webpack 4.44.x. Fix #5243 (thanks @RollinSafary)
  • There is a new npm script npm run plugin.spine.runtimes which will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo into plugins/spine/ in order for this to work.
  • Spine Game Objects can now be rendered to Render Textures. Fix #5184 (thanks @Kitsee)
  • Using > 128 Spine objects in a Container would cause a WebGL: INVALID_OPERATION: vertexAttribPointer: no ARRAY_BUFFER is bound and offset is non-zero error if you added any subsequent Spine objects to the Scene. There is now no limit. Fix #5246 (thanks @d7561985)
  • The Spine Plugin will now work in HEADLESS mode without crashing. Fix #4988 (thanks @raimon-segura)
  • Spine Game Objects now use -1 as their default blend mode, which means 'skip setting it'.
  • The Spine TypeScript defs have been updated for the latest version of the plugin and to add SpineContainers.
  • The SpineGameObject.setAnimation method will now use the trackIndex parameter if ignoreIfPlaying is set and run the check against this track index. Fix #4842 (thanks @vinerz)
  • The SpineFile will no longer throw a warning if adding a texture into the Texture Manager that already exists. This allows you to have multiple Spine JSON use the same texture file, however, it also means you now get no warning if you accidentally load a texture that exists, so be careful with your keys! Fix #4947 (thanks @Nomy1)
  • The Spine Plugin destroy method will now no longer remove the Game Objects from the Game Object Factory, or dispose of the Scene Renderer. This means when a Scene is destroyed, it will keep the Game Objects in the factory for other Scene's to use. Fix #5279 (thanks @Racoonacoon)
  • SpinePlugin.gameDestroy is a new method that is called if the Game instance emits a destroy event. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.

Animation API New Features and Updates

If you use Animations in your game, please read the following important API changes in 3.50:

The Animation API has had a significant overhaul to improve playback handling. Instead of just playing an animation based on its global key, you can now supply a new PlayAnimationConfig object instead, which allows you to override any of the default animation settings, such as duration, delay and yoyo (see below for the full list). This means you no longer have to create lots of duplicate animations just to change properties such as duration, and can now set them dynamically at run-time as well.

  • The Animation class no longer extends EventEmitter, as it no longer emits any events directly. This means you cannot now listen for events directly from an Animation instance. All of the events are now dispatched by the Game Objects instead.
  • All of the SPRITE_ANIMATION_KEY events have been removed. Instead, please use the new events which all carry the frameKey parameter, which can be used to handle frame specific events.
  • ANIMATION_UPDATE_EVENT is a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.
  • ANIMATION_STOP_EVENT is a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of the stop methods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)
  • The Game Object Component.Animation component has been renamed to AnimationState and has moved namespace. It's now in Phaser.Animations instead of GameObjects.Components to help differentiate it from the Animation class when browsing the documentation.
  • The play, playReverse, playAfterDelay, playAfterRepeat and chain Sprite and Animation Component methods can now all take a Phaser.Types.Animations.PlayAnimationConfig configuration object, as well as a string, as the key parameter. This allows you to override any default animation setting with those defined in the config, giving you far greater control over animations on a Game Object level, without needing to globally duplicate them.
  • AnimationState.create is a new method that allows you to create animations directly on a Sprite. These are not global and never enter the Animation Manager, instead risiding within the Sprite itself. This allows you to use the same keys across both local and global animations and set-up Sprite specific local animations.
  • All playback methods: play, playReverse, playAfterDelay and playAfterRepeat will now check to see if the given animation key exists locally on the Sprite first. If it does, it's used, otherwise it then checks the global Animation Manager for the key instead.
  • AnimationState.skipMissedFrames is now used when playing an animation, allowing you to create animations that run at frame rates far exceeding the refresh rate, or that will update to the correct frame should the game lag. Feature #4232 (thanks @colorcube)
  • AnimationManager.addMix is a new method that allows you to create mixes 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.
  • AnimationManager.getMix is a new method that will return the mix duration between the two given animations.
  • AnimationManager.removeMix is a new method that will remove the mixture between either two animations, or all mixtures for the given animation.
  • AnimationState.remove is a new method that will remove a locally stored Animation instance from a Sprite.
  • AnimationState.get is a new method that will return a locally stored Animation instance from the Sprite.
  • AnimationState.exists is a new method that will check if a locally stored Animation exists on the Sprite.
  • The internal AnimationState.remove method has been renamed to globalRemove.
  • AnimationState.textureManager is a new property that references the global Texture Manager.
  • AnimationState.anims is a new property that contains locally created Animations in a Custom Map.
  • AnimationState.play and Sprite.play no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • AnimationState.playReverse and Sprite.playReverse no longer accept a startFrame parameter. Please set it via the PlayAnimationConfig instead.
  • The AnimationState.delayedPlay method has been renamed to playAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration.
  • The AnimationState.stopOnRepeat method has been renamed to stopAfterRepeat
  • The AnimationState.getCurrentKey method has been renamed to getName.
  • AnimationState.getFrameName is a new method that will return the key of the current Animation Frame, if an animation has been loaded.
  • AnimationState.playAfterDelay and Sprite.playAfterDelay are new methods that will play the given animation after the delay in ms expires.
  • AnimationState.playAfterRepeat and Sprite.playAfterRepeat are new methods that will play the given animation after the current animation finishes repeating. You can also specify the number of repeats allowed left to run.
  • The AnimationState.chain method is now available on the Sprite class.
  • The AnimationState.stopAfterDelay method is now available on the Sprite class.
  • The AnimationState.stopAfterRepeat method is now available on the Sprite class.
  • The AnimationState.stopOnFrame method is now available on the Sprite class.
  • AnimationManager.createFromAseprite is a new method that allows you to use animations created in the Aseprite editor directly in Phaser. Please see the comprehensive documentation for this method for full details on how to do this.
  • AnimationState now handles all of the loading of the animation. It no longer has to make calls out to the Animation Manager or Animation instance itself and will load the animation data directly, replacing as required from the optional PlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.
  • The PlayAnimationConfig.frameRate property lets you optionally override the animation frame rate.
  • The PlayAnimationConfig.duration property lets you optionally override the animation duration.
  • The PlayAnimationConfig.delay property lets you optionally override the animation delay.
  • The PlayAnimationConfig.repeat property lets you optionally override the animation repeat counter.
  • The PlayAnimationConfig.repeatDelay property lets you optionally override the animation repeat delay value.
  • The PlayAnimationConfig.yoyo property lets you optionally override the animation yoyo boolean.
  • The PlayAnimationConfig.showOnStart property lets you optionally override the animation show on start value.
  • The PlayAnimationConfig.hideOnComplete property lets you optionally override the animation hide on complete value.
  • The PlayAnimationConfig.startFrame property lets you optionally set the animation frame to start on.
  • The PlayAnimationConfig.timeScale property lets you optionally set the animation time scale factor.
  • AnimationState.delayCounter is a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animation START events fire. Fix #4426 (thanks @bdaenen)
  • AnimationState.hasStarted is a new boolean property that allows you to tell if the current animation has started playing, or is still waiting for a delay to expire.
  • AnimationState.showOnStart is a new boolean property that controls if the Game Object should have setVisible(true) called on it when the animation starts.
  • AnimationState.hideOnComplete is a new boolean property that controls if the Game Object should have setVisible(false) called on it when the animation completes.
  • The AnimationState.chain method docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does!
  • The AnimationState.setDelay method has been removed. It never actually worked and you can now perform the same thing by calling either playAfterDelay or setting the delay property in the play config.
  • The AnimationState.getDelay method has been removed. You can now read the delay property directly.
  • The AnimationState.setRepeat method has been removed. You can achieve the same thing by setting the repeat property in the play config, or adjusting the public repeatCounter property if the animation has started.
  • AnimationState.handleStart is a new internal private method that handles the animation start process.
  • AnimationState.handleRepeat is a new internal private method that handles the animation repeat process.
  • AnimationState.handleStop is a new internal private method that handles the animation stop process.
  • AnimationState.handleComplete is a new internal private method that handles the animation complete process.
  • AnimationState.emitEvents is a new internal private method that emits animation events, cutting down on duplicate code.
  • The AnimationState.restart method has a new optional boolean parameter resetRepeats which controls if you want to reset the repeat counter during the restart, or not.
  • Animation.getTotalFrames is a new method that will return the total number of frames in the animation. You can access it via this.anims.currentAnim.getTotalFrames from a Sprite.
  • Animation.calculateDuration is a new method that calculates the duration, frameRate and msPerFrame for a given animation target.
  • The BuildGameObjectAnimation function now uses the PlayAnimationConfig object to set the values.
  • Sprite.playReverse is a new method that allows you to play the given animation in reverse on the Sprite.
  • Sprite.playAfterDelay is a new method that allows you to play the given animation on the Sprite after a delay.
  • Sprite.stop is a new method that allows you to stop the current animation on the Sprite.
  • AnimationManager.load has been removed as it's no longer required.
  • AnimationManager.staggerPlay has been fixed so you can now pass in negative stagger values.
  • AnimationManager.staggerPlay has a new optional boolean parameter staggerFirst, which allows you to either include or exclude the first child in the stagger calculations.
  • The Animation.completeAnimation method has been removed as it's no longer required.
  • The Animation.load method has been removed as it's no longer required.
  • The Animation.setFrame method has been removed as it's no longer required.
  • The Animation.getFirstTick method has no longer needs the includeDelay parameter, as it's handled by AnimationState now.
  • The Animation.getFrames method has a new optional boolean parameter sortFrames which will run a numeric sort on the frame names after constructing them, if a string-based frame is given.
  • Types.Animations.Animation has a new boolean property sortFrames, which lets Phaser numerically sort the generated frames.
  • AnimationState.timeScale is a new public property that replaces the old private _timeScale property.
  • AnimationState.delay is a new public property that replaces the old private _delay property.
  • AnimationState.repeat is a new public property that replaces the old private _repeat property.
  • AnimationState.repeatDelay is a new public property that replaces the old private _repeatDelay property.
  • AnimationState.yoyo is a new public property that replaces the old private _yoyo property.
  • AnimationState.inReverse is a new public property that replaces the old private _reverse property.
  • AnimationState.startAnimation is a new public method that replaces the old private _startAnimation method.
  • The AnimationState.getProgress method has been fixed so it will return correctly if the animation is playing in reverse.
  • The AnimationState.globalRemove method will now always be called when an animation is removed from the global Animation Manager, not just once.
  • The AnimationState.getRepeat method has now been removed. You can get the value from the repeat property.
  • The AnimationState.setRepeatDelay method has now been removed. You can set the value using the repeatDelay config property, or changing it at run-time.
  • AnimationState.complete is a new method that handles the completion in animation playback.
  • The AnimationState.setTimeScale method has now been removed. You can set the value using the timeScale config property, or changing it at run-time.
  • The AnimationState.getTimeScale method has now been removed. You can read the value using the timeScale property.
  • The AnimationState.getTotalFrames method has been fixed and won't error if called when no animation is loaded.
  • The AnimationState.setYoyo method has now been removed. You can set the value using the yoyo config property, or changing it at run-time.
  • The AnimationState.getYoyo method has now been removed. You can read the value using the yoyo property.
  • The AnimationState.stopAfterRepeat method now has an optional parameter repeatCount, so you can tell the animation to stop after a specified number of repeats, not just 1.
  • When playing an animation in reverse, if it reached the first frame and had to repeat, it would then jump to the frame before the final frame and carry on, skipping out the final frame.
  • The AnimationState.updateFrame method has now been removed. Everything is handled by setCurrentFrame instead, which removes one extra step out of the update process.
  • GenerateFrameNames will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers will now console.warn if the generated frame isn't present in the texture, which should help with debugging animation creation massively.
  • GenerateFrameNumbers would include the __BASE frame by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.
  • GenerateFrameNumbers can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.
  • GenerateFrameNames can now accept the start and end parameters in reverse order, meaning you can now do { start: 10, end: 1 } to create the animation in reverse.

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • WebGLRenderer.setInt1iv will allow you to look-up and set a 1iv uniform on the given shader.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.
  • You can now use this.renderer from within a Scene, as it's now a Scene-level property and part of the Injection Map.
  • Clock.addEvent can now take an existing TimerEvent object, as well as a config object. If a TimerEvent is given it will be removed from the Clock, reset and then added. This allows you to pool TimerEvents rather than constantly create and delete them. Fix #4115 (thanks @jcyuan)
  • Clock.removeEvent is a new method that allows you to remove a TimerEvent, or an array of them, from all internal lists of the current Clock.
  • Group.getMatching is a new method that will return any members of the Group that match the given criteria, such as getMatching('visible', true) (thanks @atursams)
  • ArcadePhysics.disableUpdate is a new method that will prevent the Arcade Physics World update method from being called when the Scene updates. By disabling it, you're free to call the update method yourself, passing in your own delta and time values.
  • ArcadePhysics.enableUpdate is a new method that will make the Arcade Physics World update in time with the Scene update. This is the default, so only call this if you have specifically disabled it previously.
  • ArcadeWorldConfig.customUpdate is a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. If true the World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)
  • Utils.Array.SortByDigits is a new function that takes the given array of strings and runs a numeric sort on it, ignoring any non-digits.
  • GroupCreateConfig, which is used when calling Group.createMultiple or Group.createFromConfig, can now accept the following new properties: setOrigin: { x, y, stepX, stepY } which are applied to the items created by the Group.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Earcut has now been exposed and is available via Geom.Polygon.Earcut and is fully documented.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • The TextureTintStripPipeline now extends TextureTintPipeline and just changes the topolgy, vastly reducing the filesize.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.
  • global.Phaser = Phaser has been removed, as it's no longer required by the UMD loader, which should make importing in Angular 10 easier. Fix #5212 (thanks @blackyale)
  • Pointer.downTime now stores the event timestamp of when the first button on the input device was pressed down, not just when button 1 was pressed down.
  • Pointer.upTime now stores the event timestamp of when the final depressed button on the input device was released, not just when button 1 was released.
  • The Pointer.getDuration method now uses the new Pointer downTime and upTime values, meaning it will accurately report the duration of when any button is being held down, not just the primary one. Fix #5112 (thanks @veleek)
  • The BaseShader default vertex shader now includes the outTexCoord vec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok)
  • When using the GameObjectCreator for Containers you can now specify the children property in the configuration object.
  • WebGLRenderer.finalType is a new boolean property that signifies if the current Game Object being rendered is the final one in the list.
  • The WebGLRenderer.updateCanvasTexture method will now set gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL to true, which should stop issues where you update a Text Game Object, having added a Render Texture or Spine Game Object to the Scene after it, which switches the PMA setting. Fix #5064 #5155 (thanks @hugoruscitti @immangrove-supertree)
  • Textures.Parsers.JSONHash will now perform a hasOwnProperty check when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes from JSON.parse. Fix #4768 (thanks @RollinSafary)
  • The Camera3D Plugin has been rebuilt for Phaser 3.50 and the webpack config updated. This plugin is now considered deprecated and will not be updated beyond this release.
  • Tween.seek will no longer issue a console warning for 'Tween.seek duration too long', it's now up to you to check on the performance of tween seeking.
  • WebGLRenderer.previousPipeline is a new property that is set during a call to clearPipeline and used during calls to rebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.
  • The WebGLRenderer.rebindPipeline method has been changed slightly. Previously, you had to specify the pipelineInstance, but this is now optional. If you don't, it will use the new previousPipeline property instead. If not set, or none given, it will now return without throwing gl errors as well.
  • If inputWindowEvents is set in the Game Config, then the MouseManager will now listen for the events on window.top instead of just window, which should help in situations where the pointer is released outside of an embedded iframe. Fix #4824 (thanks @rexrainbow)
  • Types.GameObjects.Text.GetTextSizeObject is a new type def for the GetTextSize function results.
  • The Arcade.Body.resetFlags method has a new optional boolean parameter clear. If set, it clears the wasTouching flags on the Body. This happens automatically when Body.reset is called. Previous to this, the flags were not reset until the next physics step (thanks @samme)
  • Utils.Array.StableSort has been recoded. It's now based on Two-Screens stable sort 0.1.8 and has been updated to fit into Phaser better and no longer create any window bound objects. The inplace function has been removed, just call StableSort(array) directly now. All classes that used StableSort.inplace have been updated to call it directly.
  • If a Scene is paused, or sent to sleep, it will automatically call Keyboard.resetKeys. This means that if you hold a key down, then sleep or pause a Scene, then release the key and resume or wake the Scene, it will no longer think it is still being held down (thanks @samme)
  • Actions.setOrigin will now call updateDisplayOrigin on the items array, otherwise the effects can't be seen when rendering.
  • You can now set the ArcadeWorld.fixedStep property via the ArcadeWorldConfig object (thanks @samme)
  • Utils.Array.NumerArray can now accept the start and end parameters in reverse order, i.e. 10, 1 will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.

Namespace Updates

  • The Phaser.Curves.MoveTo function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.DOM.GetInnerHeight function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Bob class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsManager class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.LightsPlugin class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.Particles.EmitterOp class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.GetTextSize function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.MeasureText function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.GameObjects.TextStyle function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Input.CreatePixelPerfectHandler function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapCirc function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Components.OverlapRect function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Arcade.Tilemap namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Components namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.MatterGameObject class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Physics.Matter.PointerConstraint class has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetPhysicsPlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Scenes.GetScenePlugins function has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Structs.Events namespace has now been exposed on the Phaser namespace (thanks @samme)
  • The Phaser.Tilemaps.Parsers.Tiled function has now been exposed on the Phaser namespace (thanks @samme)
  • Every single Tilemap.Component function has now been made public. This means you can call the Component functions directly, should you need to, outside of the Tilemap system.

Bug Fixes

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)
  • The GridAlign action didn't work if only the height parameter was set. Fix #5019 (thanks @halilcakar)
  • The Color.HSVToRGB function has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX)
  • Previously, the easeParams array within a Tweens props object, or a multi-object tween, were ignored and it was only used if set on the root Tween object. It will now work correctly set at any depth. Fix #4292 (thanks @willblackmore)
  • When using Camera.setRenderToTexture its zoom and rotation values would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok)
  • GameObjects.Shape.Grid would render a white fill even if you passed undefined as the fill color in the constructor. It now doesn't render cells if no fill color is given.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs, and TypeScript definitions, either by reporting errors, fixing them, or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360 @volkans80 @jaabberwocky @maikthomas @atursams @LearningCode2023 @DylanC @BenjaminDRichards

- JavaScript
Published by photonstorm over 5 years ago

phaser - Phaser v3.50.0 Beta 2

WebGL Pipeline Updates

If you use a custom WebGL Pipeline in your game, you must update in order to use Phaser 3.50.

Due to the huge amount of work that has taken place in this area, all of the pipelines have been renamed. If you extend any of these pipelines or use them in your game code (referenced by name), then please update accordingly. The name changes are:

  • TextureTintPipeline is now called the MultiPipeline.
  • TextureTintStripPipeline is now called the RopePipeline.
  • ForwardDiffuseLightPipeline is now called the LightPipeline.

To match the new pipeline names, the shader source code has also been renamed.

  • ForwardDiffuse.frag is now called Light.frag.
  • TextureTint.frag is now called Multi.frag.
  • TextureTint.vert is now called Multi.vert.

Other pipeline changes are as follows:

  • Types.Renderer.WebGL.WebGLPipelineConfig is a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.
  • Types.Renderer.WebGL.WebGLPipelineAttributesConfig is a new TypeDef that helps you easily configure the attributes for your own Custom Pipelines when using TypeScript and also provides better JSDocs.
  • All pipelines will now work out the renderer property automatically, so it's no longer required in the config.
  • All pipelines will now work out the gl property automatically, so it's no longer required in the config.
  • All pipelines will now extract the name property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexCapacity property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexSize property from the config, allowing you to set it externally.
  • All pipelines will now extract the vertexData property from the config, allowing you to set it externally.
  • All pipelines will now extract the attributes property from the config, allowing you to set it externally.
  • All pipelines will now extract the topology property from the config, allowing you to set it externally.

Single Pipeline

There is also a new pipeline called SinglePipeline, created to emulate the old TextureTintPipeline. This special pipeline uses just a single texture and makes things a lot easier if you wish to create a custom pipeline, but not have to recode your shaders to work with multiple textures. Instead, just extend SinglePipeline, where-as before you extended the TextureTintPipeline and you won't have to change any of your shader code. However, if you can, you should update it to make it perform faster, but that choice is left up to you.

WebGL Multi-Texture Rendering

The Multi Pipeline (previously the Texture Tint Pipeline) has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on draw call-bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture that was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead, it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLPipeline.forceZero is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.
  • Renderer.WebGL.Utils.parseFragmentShaderMaxTextures is a new function that will take fragment shader source and search it for %count% and %forloop% declarations, replacing them with the required GLSL for multi-texture support, returning the modified source.

Light Pipeline Changes

The Light Pipeline (previously called the Forward Diffuse Light Pipeline), which is responsible for rendering lights under WebGL, has been rewritten to work with the new Multi Pipeline features. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh and Quad Game Objects now support rendering with normal maps.
  • The Graphics Game Objects now support rendering in Light2d. You can even use normal map textures for the texture fills.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • All Shape Game Objects (Rectangle, IsoBox, Star, Polygon, etc) now support rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Both Static and Dynamic Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Lights

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

WebGL ModelViewProjection API Changes

The ModelViewProjection object contained a lot of functions that Phaser never used internally. These have now been moved to external functions, which can be easily excluded from Custom builds to save space.

If you used any of them in your code, please update to the new function names below:

  • Phaser.Renderer.WebGL.MVP is a new namespace under which the Model View Projection functions now live.
  • projIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectIdentity
  • projPersp is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectPerspective
  • modelRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateX
  • modelRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateY
  • modelRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateZ
  • viewLoad is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad
  • viewRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateX
  • viewRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateY
  • viewRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateZ
  • viewScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewScale
  • viewTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewTranslate
  • modelIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Identity
  • modelScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Scale
  • modelTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Translate
  • viewIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewIdentity
  • viewLoad2D is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad2D
  • projOrtho is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectOrtho
  • Phaser.Renderer.WebGL.MVP.SetIdentity is a new function the others use, to save on space.

BitmapText New Features, Updates and API Changes

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and per-corner tint colors.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y coordinates. The character data includes the code, position, dimensions, and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.

New Features

  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Intersects.GetLineToPoints is a new function that checks for the closest point of intersection between a line segment and an array of points, where each pair of points form a line segment.
  • Geom.Intersects.GetRaysFromPointToPolygon is a new function that emits rays out from the given point and detects for intersection against all given polygons, returning the points of intersection in the results array.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Geom.Polygon.Simplify is a new function that takes a polygon and simplifies the points by running them through a combination of Douglas-Peucker and Radial Distance algorithms, potentially dramatically reducing the number of points while retaining its shape.
  • WebGLRenderer.setInt1iv will allow you to look-up and set a 1iv uniform on the given shader.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems, if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
  • TweenManager.getTweensOf has a new parameter includePending. If set, it will also check the pending tweens for the given targets and return those in the results as well. Fix #5260 (thanks @pcharest2000)
  • WebGLPipeline.hasBooted is a new boolean property that tracks if the pipeline has been booted or not, which is now far more important in 3.5 than in previous versions. This is checked in the WebGLRenderer.addPipeline method, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)
  • The WebGL Renderer will now add the pipelines during the boot method, instead of init.

Updates and API Changes

  • Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • The TextureTintStripPipeline now extends TextureTintPipeline and just changes the topolgy, vastly reducing the filesize.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.
  • The constant Phaser.Renderer.WebGL.BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_BYTE value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.UNSIGNED_SHORT value has been removed as it wasn't used internally.
  • The constant Phaser.Renderer.WebGL.FLOAT value has been removed as it wasn't used internally.

Bug Fixes

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • RenderTexture.fill would fail to fill the correct area under WebGL if the RenderTexture wasn't the same size as the Canvas. It now fills the given region properly.
  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
  • The ProcessQueue was emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@samme @16patsle @scott20145 @khasanovbi @mk360

- JavaScript
Published by photonstorm almost 6 years ago

phaser - Phaser v3.50.0 Beta 1

WebGL Multi-Texture Rendering

The Texture Tint Pipeline has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on drawcall-bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same, unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture tha was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones and resets the active texture counter.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLPipeline.forceZero is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.

Forward Diffuse Light Pipeline API Changes

This Light2D pipeline, which is responsible for rendering lights under WebGL, has been rewritten to work with the new Texture Tint Pipeline functions. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh and Quad Game Objects now support rendering with normal maps.
  • The Graphics Game Objects now support rendering in Light2d. You can even use normal map textures for the texture fills.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • All Shape Game Objects (Rectangle, IsoBox, Star, Polygon, etc) now support rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Both Static and Dynamic Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Lights

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

WebGL ModelViewProjection API Changes

The ModelViewProjection object contained a lot of functions that Phaser never used internally. These have now been moved to external functions, which can be easily excluded from Custom builds to save space.

If you used any of them in your code, please update to the new function names below:

  • Phaser.Renderer.WebGL.MVP is a new namespace under which the Model View Projection functions now live.
  • projIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectIdentity
  • projPersp is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectPerspective
  • modelRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateX
  • modelRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateY
  • modelRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateZ
  • viewLoad is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad
  • viewRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateX
  • viewRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateY
  • viewRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateZ
  • viewScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewScale
  • viewTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewTranslate
  • modelIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Identity
  • modelScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Scale
  • modelTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Translate
  • viewIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewIdentity
  • viewLoad2D is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad2D
  • projOrtho is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectOrtho
  • Phaser.Renderer.WebGL.MVP.SetIdentity is a new function the others use, to save on space.

BitmapText New Features, Updates and API Changes

  • BitmapText.setCharacterTint is a new method that allows you to set a tint color (either additive, or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and a per-corner tint color.
  • BitmapText.setWordTint is a new method that allows you to set a tint color (either additive, or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
  • BitmapText.setDropShadow is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
  • BitmapTextWebGLRenderer has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by GetBitmapTextSize. This has reduced the number of calculations made in the function dramatically, as it no longer has work out glyph advancing or offsets during render, but only when the text content updates.
  • BitmapText.getCharacterAt is a new method that will return the character data from the BitmapText at the given x and y corodinates. The character data includes the code, position, dimensions and glyph information.
  • The BitmapTextSize object returned by BitmapText.getTextBounds has a new property called characters which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
  • ParseXMLBitmapFont will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
  • ParseXMLBitmapFont will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: this.add.sprite(x, y, fontName, 'A').
  • BitmapTextWord, BitmapTextCharacter and BitmapTextLines are three new type defs that are now part of the BitmapTextSize config object, as returned by getTextBounds. This improves the TypeScript defs and JS Docs for this object.
  • The signature of the ParseXMLBitmapFont function has changed. The frame parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
  • The BitmapText.getTextBounds method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
  • The GetBitmapTextSize function used Math.round on the values, if the round parameter was true, which didn't create integers. It now uses Math.ceil instead to give integer results.
  • The GetBitmapTextSize function has a new boolean parameter updateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
  • BitmapText.preDestroy is a new method that will tidy-up all of the BitmapText data during object destruction.
  • BitmapText.dropShadowX is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowY is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
  • BitmapText.dropShadowColor is a new property that sets the color of the Bitmap Text drop shadow.
  • BitmapText.dropShadowAlpha is a new property that sets the alpha of the Bitmap Text drop shadow.
  • BatchChar is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
  • If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a console.warn.
  • Setting the color value in the DynamicBitmapText.setDisplayCallback would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
  • If you apply setSize to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
  • ParseXMLBitmapFont has a new optional parameter texture. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.

New Features

  • WebGLRenderer.setInt1iv will allow you to look-up and set a 1iv uniform on the given shader.
  • Geom.Intersects.GetLineToLine is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the z property holding the distance value.
  • Geom.Intersects.GetLineToPolygon is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
  • Geom.Polygon.Translate is a new function that allows you to translate all the points of a polygon by the given values.
  • Phaser.Types.Math.Vector3Like is a new data type representing as Vector 3 like object.
  • Phaser.Types.Math.Vector4Like is a new data type representing as Vector 4 like object.
  • Transform.getLocalPoint is a new method, available on all Game Objects, that takes an x / y pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
  • The KeyboardPlugin will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
  • Display.Color.GetColorFromValue is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
  • Utils.String.RemoveAt is a new function that will remove a character from the given index in a string and return the new string.
  • Frame.setUVs is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.

Updates and API Changes

  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • The TextureTintStripPipeline now extends TextureTintPipeline and just changes the topolgy, vastly reducing the filesize.
  • TransformMatrix.getXRound is a new method that will return the X component, optionally passed via Math.round.
  • TransformMatrix.getYRound is a new method that will return the Y component, optionally passed via Math.round.
  • The KeyboardPlugin no longer emits keydown_ events. These were replaced with keydown- events in v3.15. The previous event string was deprecated in v3.20.
  • The KeyboardPlugin no longer emits keyup_ events. These were replaced with keyup- events in v3.15. The previous event string was deprecated in v3.20.
  • The ScaleManager.updateBounds method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the updateBounds method directly, yourself.

Bug Fixes

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
  • The KeyboardManager and KeyboardPlugin were both still checking for the InputManager.useQueue property, which was removed several versions ago.
  • In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
  • Calling Rectangle.setSize() wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@samme @16patsle @scott20145

- JavaScript
Published by photonstorm almost 6 years ago

phaser - Phaser v3.25.0 Beta 0

WebGL Multi-Texture Rendering

The Texture Tint Pipeline has had its core flow rewritten to eliminate the need for constantly creating batch objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on drawcall-bound systems.

All of the internal functions, such as batchQuad and batchSprite have been updated to use the new method of texture setting. The method signatures all remain the same, unless indicated below.

  • Config.render.maxTextures is a new game config setting that allows you to control how many texture units will be used in WebGL.
  • WebGL.Utils.checkShaderMax is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
  • The property WebGLRenderer.currentActiveTextureUnit has been renamed to currentActiveTexture.
  • WebGLRenderer.startActiveTexture is a new read-only property contains the current starting active texture unit.
  • WebGLRenderer.maxTextures is a new read-only property that contains the maximum number of texture units WebGL can use.
  • WebGLRenderer.textureIndexes is a new read-only array that contains all of the available WebGL texture units.
  • WebGLRenderer.tempTextures is a new read-only array that contains temporary WebGL textures.
  • The WebGLRenderer.currentTextures property has been removed, as it's no longer used.
  • TextureSource.glIndex is a new property that holds the currently assigned texture unit for the Texture Source.
  • TextureSource.glIndexCounter is a new property that holds the time the index was assigned to the Texture Source.
  • WebGLRenderer.currentTextures has been removed, as it's no longer used internally.
  • WebGLRenderer.setBlankTexture no longer has a force parameter, as it's set by default.
  • The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
  • The Texture Tint vertex and fragment shaders have been updated to support the inTexId float attribute and dynamic generation.
  • The Texture Tint Pipeline has a new attribute, inTexId which is a gl.FLOAT.
  • TextureTintPipeline.bind is a new method that sets the uMainSampler uniform.
  • The TextureTintPipeline.requireTextureBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.pushBatch method has been removed, as it's no longer required.
  • The TextureTintPipeline.maxQuads property has been removed, as it's no longer required.
  • The TextureTintPipeline.batches property has been removed, as it's no longer required.
  • TextureTintPipeline.flush has been rewritten to support multi-textures.
  • TextureTintPipeline.flush no longer creates a sub-array if the batch is full, but instead uses bufferData for speed.
  • WebGLPipeline.currentUnit is a new property that holds the most recently assigned texture unit. Treat as read-only.
  • WebGLRenderer.setTextureSource is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
  • The WebGLRenderer.setTexture2D method has been updated to use the new texture unit assignment. It no longer takes the textureUnit or flush parameters and these have been removed from its method signature.
  • WebGLRenderer.setTextureZero is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
  • WebGLRenderer.clearTextureZero is a new method that clears the texture tha was bound to unit zero.
  • WebGLRenderer.textureZero is a new property that holds the currently bound unit zero texture.
  • WebGLRenderer.normalTexture is a new property that holds the currently bound normal map (texture unit one).
  • WebGLRenderer.setNormalMap is a new method that sets the current normal map texture.
  • WebGLRenderer.clearNormalMap is a new method that clears the current normal map texture.
  • WebGLRenderer.resetTextures is a new method that flushes the pipeline, resets all textures back to the temporary ones and resets the active texture counter.
  • WebGLPipeline.boot will now check all of the attributes and store the pointer location within the attribute entry.
  • WebGLPipeline.bind no longer looks-up and enables every attribute, every frame. Instead it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
  • WebGLRenderer.isNewNormalMap is a new method that returns a boolean if the given parameters are not currently used.
  • WebGLPipeline.forceZero is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
  • WebGLPipeline.setAttribPointers is a new method that will set the vertex attribute pointers for the pipeline.
  • WebGLRenderer.unbindTextures is a new method that will activate and then null bind all WebGL textures.

Forward Diffuse Light Pipeline API Changes

This Light2D pipeline, which is responsible for rendering lights under WebGL, has been rewritten to work with the new Texture Tint Pipeline functions. Lots of redundant code has been removed and the following changes and improvements took place:

  • The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
  • Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
  • The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
  • The TileSprite Game Objects now support rendering with normal maps.
  • Mesh and Quad Game Objects now support rendering with normal maps.
  • The Graphics Game Objects now support rendering in Light2d. You can even use normal map textures for the texture fills.
  • Particle Emitter Game Object now supports rendering in Light2d.
  • All Shape Game Objects (Rectangle, IsoBox, Star, Polygon, etc) now support rendering in Light2d.
  • The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
  • Both Static and Dynamic Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
  • The pipeline will no longer look-up and set all of the light uniforms unless the Light is dirty.
  • The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
  • The ForwardDiffuseLightPipeline.defaultNormalMap property has changed, it's now an object with a glTexture property that maps to the pipelines default normal map.
  • The ForwardDiffuseLightPipeline.boot method has been changed to now generate a default normal map.
  • The ForwardDiffuseLightPipeline.onBind method has been removed as it's no longer required.
  • The ForwardDiffuseLightPipeline.setNormalMap method has been removed as it's no longer required.
  • ForwardDiffuseLightPipeline.bind is a new method that handles setting-up the shader uniforms.
  • The ForwardDiffuseLightPipeline.batchTexture method has been rewritten to use the Texture Tint Pipeline function instead.
  • The ForwardDiffuseLightPipeline.batchSprite method has been rewritten to use the Texture Tint Pipeline function instead.
  • ForwardDiffuseLightPipeline.lightCount is a new property that stores the previous number of lights rendered.
  • ForwardDiffuseLightPipeline.getNormalMap is a new method that will look-up and return a normal map for the given object.

Lights

  • Light.dirty is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
  • Light has been recoded so that all of its properties are now setters that activate its dirty flag.
  • LightsManager.destroy will now clear the lightPool array when destroyed, where-as previously it didn't.
  • LightsManager.cull now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)

WebGL ModelViewProjection API Changes

The ModelViewProjection object contained a lot of functions that Phaser never used internally. These have now been moved to external functions, which can be easily excluded from Custom builds to save space.

If you used any of them in your code, please update to the new function names below:

  • Phaser.Renderer.WebGL.MVP is a new namespace under which the Model View Projection functions now live.
  • projIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectIdentity
  • projPersp is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectPerspective
  • modelRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateX
  • modelRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateY
  • modelRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.RotateZ
  • viewLoad is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad
  • viewRotateX is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateX
  • viewRotateY is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateY
  • viewRotateZ is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewRotateZ
  • viewScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewScale
  • viewTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewTranslate
  • modelIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Identity
  • modelScale is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Scale
  • modelTranslate is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.Translate
  • viewIdentity is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewIdentity
  • viewLoad2D is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ViewLoad2D
  • projOrtho is now available as a stand-alone function Phaser.Renderer.WebGL.MVP.ProjectOrtho
  • Phaser.Renderer.WebGL.MVP.SetIdentity is a new function the others use, to save on space.

New Features

  • WebGLRenderer.setInt1iv will allow you to look-up and set a 1iv uniform on the given shader.

Updates and API Changes

  • Config.batchSize has been increased from 2000 to 4096.
  • Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
  • StaticTilemapLayer.upload will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
  • StaticTilemapLayer now includes the ModelViewProjection mixin, so it doesn't need to modify the pipeline during rendering.
  • WebGLRenderer.textureFlush is a new property that keeps track of the total texture flushes per frame.
  • The TextureTintStripPipeline now extends TextureTintPipeline and just changes the topolgy, vastly reducing the filesize.

Bug Fixes

  • RenderTexture.resize (which is called from setSize) wouldn't correctly set the TextureSource.glTexture property, leading to bindTexture: attempt to use a deleted object errors under WebGL.
  • The MatterAttractors plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was first in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@samme

- JavaScript
Published by photonstorm almost 6 years ago

phaser - Phaser v3.24.1

Version 3.24.1 - Rem - 14th July 2020

  • Reverted the PR that added the parent transform to a Static Tilemap Layer as it broke tilemap rendering when the camera was zoomed (thanks @kainage)
  • Fixed an error with the use of the Vector2Like type in the Math.RotateTo function that caused a TypeScript error on compilation

Version 3.24.0 - Rem - 13th July 2020

Arcade Physics New Features, Updates and Fixes

  • When colliding physics groups with the search tree enabled, there was an unnecessary intersection test for each body returned by the search (thanks @samme)
  • When doing an overlap collision, there was an unnecessary intersection test for each pair of overlapping bodies (thanks @samme)
  • Sprite vs. Static Group collision tests now always use the static tree (thanks @samme)
  • Fixed a bug where if you added a static body to a sprite with scale ≠ 1, the body position was incorrect (thanks @samme)
  • If you passed in an array of children when creating a Physics Group, they didn't receive bodies. Fix #5152 (thanks @samme)
  • New types allow for better docs / TypeScript defs especially in the Factory functions: ArcadePhysicsCallback, GameObjectWithBody, GameObjectWithDynamicBody, GameObjectWithStaticBody, ImageWithDynamicBody, ImageWithStaticBody, SpriteWithDynamicBody and SpriteWithStaticBody. Fix #4994 (thanks @samme @gnesher)
  • Body.updateFromGameObject is a new method that extracts the relevant code from preUpdate, allowing you to read the body's new position and center immediately, before the next physics step. It also lets refreshBody work for dynamic bodies, where previously it would error (thanks @samme)
  • Momentum exchange wasn't working correctly vs. immovable bodies. The movable body tended to stop. Fix #4770 (thanks @samme)
  • The Body mass was decreasing the inertia instead of increasing it. Fix #4770 (thanks @samme)
  • The separation vector seemed to be incorrect, causing the slip / slide collisions. The separation is now correct for circle–circle collisions (although not fully for circle–rectangle collisions), part fix #4770 (thanks @samme)
  • The Arcade Body delta was incorrectly calculated on bodies created during the update step, causing the position to be off. Fix #5204 (thanks @zackexplosion @samme)
  • Arcade.Components.Size.setBodySize is a new method available on Arcade Physics Game Objects that allows you to set the body size. This replaces setSize which is now deprecated. Fix #4786 (thanks @wingyplus)

New Features

  • The Animation component has a new property nextAnimsQueue which allows you to sequence Sprite animations to play in order, i.e: this.mole.anims.play('digging').anims.chain('lifting').anims.chain('looking').anims.chain('lowering'); (thanks @tgroborsch)
  • Group.setActive is a new method that will set the active state of a Group, just like it does on other Game Objects (thanks @samme)
  • Group.setName is a new method that will set the name property of a Group, just like it does on other Game Objects (thanks @samme)
  • TWEEN_STOP is a new event dispatched by a Tween when it stops playback (thanks @samme @RollinSafary)
  • You can now specify an onStop callback when creating a Tween as part of the tween config, which is invoked when a Tween stops playback (thanks @samme @RollinSafary)
  • Previously, if you created a timeline and passed no tweens in the config, the timeline would be created but all config properties were ignored. Now the timeline's own properties (completeDelay, loop, loopDelay, useFrames, onStart, onUpdate, onLoop, onYoyo, onComplete, etc.) are set from the config properly (thanks @samme)
  • TextStyle.wordWrapWidth lets you set the maximum width of a line of text (thanks @mikewesthad)
  • TextStyle.wordWrapCallback is a custom function that will is responsible for wrapping the text (thanks @mikewesthad)
  • TextStyle.wordWrapCallbackScope is the scope that will be applied when the wordWrapCallback is invoked (thanks @mikewesthad)
  • TextStyle.wordWrapUseAdvanced controls whether or not to use the advanced wrapping algorithm (thanks @mikewesthad)
  • KeyboardPlugin.removeAllKeys is a new method that allows you to automatically remove all Key instances that the plugin has created, making house-keeping a little easier (thanks @samme)
  • Math.RotateTo is a new function that will position a point at the given angle and distance (thanks @samme)
  • Display.Bounds.GetBounds is a new function that will return the un-transformed bounds of the given Game Object as a Rectangle (thanks @samme)

Updates

  • The Pointer.dragStartX/YGlobal and Pointer.dragX/Y values are now populated from the worldX/Y, which means using those values directly in Input Drag callbacks will now work when the Camera is zoomed. Fix #4755 (thanks @braindx)
  • The browser field has been added to the Phaser package.json pointing to the dist/phaser.js umd build (thanks @FredKSchott)
  • Calling TimeStep.wake() while the loop is running will now cause nothing to happen, rather than sleeping and then waking again (thanks @samme)
  • Container.getBounds will no longer set the temp rect bounds to the first child of the Container by default (which would error if the child had no bounds, like a Graphics object) and instead sets it as it iterates the children (thanks @blopa)
  • File.state will now be set to the FILE_LOADING state while loading and FILE_LOADED after loading (thanks @samme)
  • BaseCamera.cull now moves some of its calculations outside of the cull loop to speed it up (thanks @samme)
  • SceneManager.createSceneFromInstance had a small refactor to avoid a pointless condition (thanks @samme)

Bug Fixes

  • Fixed a TypeError warning when importing JSON objects directly to the url argument of any of the Loader filetypes. Fix #5189 (thanks @awweather @samme)
  • The NOOP function was incorrectly imported by the Mouse and Keyboard Manager. Fix #5170 (thanks @samme @gregolai)
  • When Audio files failed to decode on loading, they would always show 'undefined' as the key in the error log, now they show the actual key (thanks @samme)
  • When the Sprite Sheet parser results in zero frames, the warning will now tell you the texture name that caused it (thanks @samme)
  • KeyboardPlugin.checkDown didn't set the duration to zero if the parameter was omitted, causing it to always return false. Fix #5146 (thanks @lozzajp)
  • If you passed in an array of children when creating a Group, they were not added and removed correctly. Fix #5151 (thanks @samme)
  • When using HTML5 Audio with pauseOnBlur (the default), if you play a sound, schedule stopping the sound (e.g., timer, tween complete callback), leave the page, and return to the page, the sound stop() will error (thanks @samme)
  • Using a Render Texture when you're also using the headless renderer would cause an error (thanks @samme)
  • Ellipse.setWidth would incorrectly set the xRadius to the diameter (thanks @rexrainbow)
  • Ellipse.setHeight would incorrectly set the yRadius to the diameter (thanks @rexrainbow)
  • When specifically setting the parent property in the Game Config to null the canvas was appended to the document body, when it should have been ignored (allowing you to add it to the dom directly). Fix #5191 (thanks @MerganThePirate)
  • Containers will now apply nested masks correctly when using the Canvas Renderer specifically (thanks @scott20145)
  • Calling Scale.startFullScreen would fail in Safari on Mac OS, throwing a fullscreenfailed error. It now triggers fullscreen mode correctly, as on other browsers. Fix #5143 (thanks @samme @novaknole)
  • Calling setCrop on a Matter Physics Sprite would throw a TypeError, but will now crop correctly. Not that it only crops the texture, the body is unaffected. Fix #5211 (thanks @MatthewRorke @samme)
  • The Static Tilemap Layer would ignore the layer rotation and parent transform when using WebGL (but worked in Canvas). Both modes now work in the same manner (thanks @cruzdanilo)
  • Calling getTextBounds on a BitmapText object would return the incorrect values if the origin had been changed, but the text itself had not, as it was using out of date dimensions. Changing the origin now automatically triggers BitmapText to be dirty, forcing the bounds to be refreshed. Fix #5121 (thanks @thenonamezz)
  • The ISO Triangle shape would skip rendering the left side of the first triangle in the batch. It now renders all ISO Triangles correctly. Fix #5164 (thanks @mattjennings)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@samme @SanderVanhove @SirJosh3917 @mooreInteractive @A-312 @lozzajp @mikewesthad @j-waters @futuremarc

- JavaScript
Published by photonstorm almost 6 years ago

phaser - Phaser v3.24.0

Arcade Physics New Features, Updates and Fixes

  • When colliding physics groups with the search tree enabled, there was an unnecessary intersection test for each body returned by the search (thanks @samme)
  • When doing an overlap collision, there was an unnecessary intersection test for each pair of overlapping bodies (thanks @samme)
  • Sprite vs. Static Group collision tests now always use the static tree (thanks @samme)
  • Fixed a bug where if you added a static body to a sprite with scale ≠ 1, the body position was incorrect (thanks @samme)
  • If you passed in an array of children when creating a Physics Group, they didn't receive bodies. Fix #5152 (thanks @samme)
  • New types allow for better docs / TypeScript defs especially in the Factory functions: ArcadePhysicsCallback, GameObjectWithBody, GameObjectWithDynamicBody, GameObjectWithStaticBody, ImageWithDynamicBody, ImageWithStaticBody, SpriteWithDynamicBody and SpriteWithStaticBody. Fix #4994 (thanks @samme @gnesher)
  • Body.updateFromGameObject is a new method that extracts the relevant code from preUpdate, allowing you to read the body's new position and center immediately, before the next physics step. It also lets refreshBody work for dynamic bodies, where previously it would error (thanks @samme)
  • Momentum exchange wasn't working correctly vs. immovable bodies. The movable body tended to stop. Fix #4770 (thanks @samme)
  • The Body mass was decreasing the inertia instead of increasing it. Fix #4770 (thanks @samme)
  • The separation vector seemed to be incorrect, causing the slip / slide collisions. The separation is now correct for circle–circle collisions (although not fully for circle–rectangle collisions), part fix #4770 (thanks @samme)
  • The Arcade Body delta was incorrectly calculated on bodies created during the update step, causing the position to be off. Fix #5204 (thanks @zackexplosion @samme)
  • Arcade.Components.Size.setBodySize is a new method available on Arcade Physics Game Objects that allows you to set the body size. This replaces setSize which is now deprecated. Fix #4786 (thanks @wingyplus)

New Features

  • The Animation component has a new property nextAnimsQueue which allows you to sequence Sprite animations to play in order, i.e: this.mole.anims.play('digging').anims.chain('lifting').anims.chain('looking').anims.chain('lowering'); (thanks @tgroborsch)
  • Group.setActive is a new method that will set the active state of a Group, just like it does on other Game Objects (thanks @samme)
  • Group.setName is a new method that will set the name property of a Group, just like it does on other Game Objects (thanks @samme)
  • TWEEN_STOP is a new event dispatched by a Tween when it stops playback (thanks @samme @RollinSafary)
  • You can now specify an onStop callback when creating a Tween as part of the tween config, which is invoked when a Tween stops playback (thanks @samme @RollinSafary)
  • Previously, if you created a timeline and passed no tweens in the config, the timeline would be created but all config properties were ignored. Now the timeline's own properties (completeDelay, loop, loopDelay, useFrames, onStart, onUpdate, onLoop, onYoyo, onComplete, etc.) are set from the config properly (thanks @samme)
  • TextStyle.wordWrapWidth lets you set the maximum width of a line of text (thanks @mikewesthad)
  • TextStyle.wordWrapCallback is a custom function that will is responsible for wrapping the text (thanks @mikewesthad)
  • TextStyle.wordWrapCallbackScope is the scope that will be applied when the wordWrapCallback is invoked (thanks @mikewesthad)
  • TextStyle.wordWrapUseAdvanced controls whether or not to use the advanced wrapping algorithm (thanks @mikewesthad)
  • KeyboardPlugin.removeAllKeys is a new method that allows you to automatically remove all Key instances that the plugin has created, making house-keeping a little easier (thanks @samme)
  • Math.RotateTo is a new function that will position a point at the given angle and distance (thanks @samme)
  • Display.Bounds.GetBounds is a new function that will return the un-transformed bounds of the given Game Object as a Rectangle (thanks @samme)

Updates

  • The Pointer.dragStartX/YGlobal and Pointer.dragX/Y values are now populated from the worldX/Y, which means using those values directly in Input Drag callbacks will now work when the Camera is zoomed. Fix #4755 (thanks @braindx)
  • The browser field has been added to the Phaser package.json pointing to the dist/phaser.js umd build (thanks @FredKSchott)
  • Calling TimeStep.wake() while the loop is running will now cause nothing to happen, rather than sleeping and then waking again (thanks @samme)
  • Container.getBounds will no longer set the temp rect bounds to the first child of the Container by default (which would error if the child had no bounds, like a Graphics object) and instead sets it as it iterates the children (thanks @blopa)
  • File.state will now be set to the FILE_LOADING state while loading and FILE_LOADED after loading (thanks @samme)
  • BaseCamera.cull now moves some of its calculations outside of the cull loop to speed it up (thanks @samme)
  • SceneManager.createSceneFromInstance had a small refactor to avoid a pointless condition (thanks @samme)

Bug Fixes

  • Fixed a TypeError warning when importing JSON objects directly to the url argument of any of the Loader filetypes. Fix #5189 (thanks @awweather @samme)
  • The NOOP function was incorrectly imported by the Mouse and Keyboard Manager. Fix #5170 (thanks @samme @gregolai)
  • When Audio files failed to decode on loading, they would always show 'undefined' as the key in the error log, now they show the actual key (thanks @samme)
  • When the Sprite Sheet parser results in zero frames, the warning will now tell you the texture name that caused it (thanks @samme)
  • KeyboardPlugin.checkDown didn't set the duration to zero if the parameter was omitted, causing it to always return false. Fix #5146 (thanks @lozzajp)
  • If you passed in an array of children when creating a Group, they were not added and removed correctly. Fix #5151 (thanks @samme)
  • When using HTML5 Audio with pauseOnBlur (the default), if you play a sound, schedule stopping the sound (e.g., timer, tween complete callback), leave the page, and return to the page, the sound stop() will error (thanks @samme)
  • Using a Render Texture when you're also using the headless renderer would cause an error (thanks @samme)
  • Ellipse.setWidth would incorrectly set the xRadius to the diameter (thanks @rexrainbow)
  • Ellipse.setHeight would incorrectly set the yRadius to the diameter (thanks @rexrainbow)
  • When specifically setting the parent property in the Game Config to null the canvas was appended to the document body, when it should have been ignored (allowing you to add it to the dom directly). Fix #5191 (thanks @MerganThePirate)
  • Containers will now apply nested masks correctly when using the Canvas Renderer specifically (thanks @scott20145)
  • Calling Scale.startFullScreen would fail in Safari on Mac OS, throwing a fullscreenfailed error. It now triggers fullscreen mode correctly, as on other browsers. Fix #5143 (thanks @samme @novaknole)
  • Calling setCrop on a Matter Physics Sprite would throw a TypeError, but will now crop correctly. Not that it only crops the texture, the body is unaffected. Fix #5211 (thanks @MatthewRorke @samme)
  • The Static Tilemap Layer would ignore the layer rotation and parent transform when using WebGL (but worked in Canvas). Both modes now work in the same manner (thanks @cruzdanilo)
  • Calling getTextBounds on a BitmapText object would return the incorrect values if the origin had been changed, but the text itself had not, as it was using out of date dimensions. Changing the origin now automatically triggers BitmapText to be dirty, forcing the bounds to be refreshed. Fix #5121 (thanks @thenonamezz)
  • The ISO Triangle shape would skip rendering the left side of the first triangle in the batch. It now renders all ISO Triangles correctly. Fix #5164 (thanks @mattjennings)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@samme @SanderVanhove @SirJosh3917 @mooreInteractive @A-312 @lozzajp @mikewesthad @j-waters @futuremarc

- JavaScript
Published by photonstorm almost 6 years ago

phaser - Phaser v3.23.0

JSDocs

The entire Phaser 3 API now has 100% complete JSDoc coverage!

The following sections had their documentation completed in this release:

  • Animations
  • Create
  • Curves
  • Geom
  • Math
  • Renderer
  • Textures
  • Tilemaps

Removed

The following features have been removed in this version of Phaser:

  • Impact Physics has been removed completely and is no longer a choice of physics system. The resulting Scene.impact property and Impact config object have also been removed.

Deprecated

The following features are now deprecated and will be removed in a future version of Phaser:

  • The Light Pipeline and associated components will be removed. This feature was never properly finished and adds too much redundant, non-optional code into the core API. The ability to load normal maps alongside textures will remain, for use in your own lighting shaders, which gives you far more control over the final effect.

New: Rope Game Object

This version of Phaser contains the brand new Rope Game Object. A Rope is a special kind of Game Object that has a repeating texture that runs in a strip, either horizontally or vertically. Unlike a Sprite, you can define how many vertices the Rope has, and can modify each of them during run-time, allowing for some really lovely effects.

Ropes can be created via the Game Object Factory in the normal way (this.add.rope()) and you should look at the examples and documentation for further implementation details.

Note that Ropes are a WebGL only feature.

New Features

  • Line.GetEasedPoints is a new function that will take a Line, a quantity, and an ease function, and returns an array of points where each point has been spaced out across the length of the Line based on the ease function given.
  • XHRSettings.withCredentials is a new boolean property that controls the withCredentials setting of the XHR Request made by the Loader. It indicates whether or not cross-site Access-Control requests should be made using credentials such as cookies, authorization headers or TLS client certificates. You can set this on a per-file basis, or global in the Game Config.
  • Config.loaderWithCredentials is the new global setting for XHRSettings.withCredentials.
  • Camera.renderToGame is a new property used in conjunction with renderToTexture. It controls if the Camera should still render to the Game canvas after rendering to its own texture or not. By default, it will render to both, but you can now toggle this at run-time.
  • Camera.setRenderToTexture has a new optional parameter renderToGame which sets the Camera.renderToGame property, controlling if the Camera should render to both its texture and the Game canvas, or just its texture.
  • The free version of Texture Packer exports a pivot property when using JSON Array or Hash, however the Texture Packer Phaser export uses the anchor property. This update allows the loaders to work with either property, regardless of which export you use (thanks @veleek)
  • get() is a new method in the HTML and Web Audio Sound Managers that will get the first sound in the manager matching the given key, if any (thanks @samme)
  • getAll() is a new method in the HTML and Web Audio Sound Managers that will get all sounds in the manager matching the given key, if any (thanks @samme)
  • removeAll() is a new method in the HTML and Web Audio Sound Managers that will remove all sounds in the manager, destroying them (thanks @samme)
  • stopByKey() is a new method in the HTML and Web Audio Sound Managers that will stop any sound in the manager matching the given key, if any (thanks @samme)
  • Rectangle.FromXY is a new function that will create the smallest Rectangle containing two coordinate pairs, handy for marquee style selections (thanks @samme)
  • PathFollower.pathDelta is a new property that holds the distance the follower has traveled from the previous point to the current one, at the last update (thanks @samme)
  • Vector2.fuzzyEquals is a new method that will check whether the Vector is approximately equal to a given Vector (thanks @samme)
  • Vector2.setAngle is a new method that will set the angle of the Vector (thanks @samme)
  • Vector2.setLength is a new method that will set the length, or magnitude of the Vector (thanks @samme)
  • Vector2.normalizeLeftHand is a new method that will rotate the Vector to its perpendicular, in the negative direction (thanks @samme)
  • Vector2.limit is a new method that will limit the length, or magnitude of the Vector (thanks @samme)
  • Vector2.reflect is a new method that will reflect the Vector off a line defined by a normal (thanks @samme)
  • Vector2.mirror is a new method that will reflect the Vector across another (thanks @samme)
  • Vector2.rotate is a new method that will rotate the Vector by an angle amount (thanks @samme)
  • Math.Angle.Random is a new function that will return a random angle in radians between -pi and pi (thanks @samme)
  • Math.Angle.RandomDegrees is a new function that will return a random angle in degrees between -180 and 180 (thanks @samme)
  • Physics.Arcade.World.fixedStep is a new boolean property that synchronizes the physics fps to the rendering fps when enabled. This can help in some cases where "glitches" can occur in the movement of objects. These glitches are especially noticeable on objects that move at constant speed and the fps are not consistent. Enabling this feature disables the fps and timeScale properties of the Arcade.World class (thanks @jjcapellan)
  • Curves.Path.getTangent is a new method that gets a unit vector tangent at a relative position on the path (thanks @samme)
  • DataManager.inc is a new method that will increase a value for the given key. If the key doesn't already exist in the Data Manager then it is increased from 0 (thanks @rexrainbow)
  • DataManager.toggle is a new method that will 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 (thanks @rexrainbow)
  • The Tiled parser will now recognize Tiled point objects and export them with point: true. Equally, Sprites generated via createFromObjects are now just set to the position of the Point object, using the Sprites dimensions. This is a breaking change, so if you are using Point objects and createFromObjects please re-test your maps against this release of Phaser (thanks @samme)
  • You can now use Blob URLs when loading Audio objects via the Loader (thanks @aucguy)
  • You can now use Blob URLs when loading Video objects via the Loader (thanks @aucguy)
  • Tiled Image Collections now have rudimentary support and will create a single tileset per image. This is useful for prototyping, but should not be used heavily in production. See #4964 (thanks @gogoprog)
  • When loading files using your own XHR Settings you can now use the new property headers to define an object containing multiple headers, all of which will be sent with the xhr request (thanks @jorbascrumps)
  • Camera.rotateTo is a new Camera effect that allows you to set the rotation of the camera to a given value of the duration specified (thanks @jan1za)

Updates

  • XHRLoader will now use the XHRSettings.withCredentials as set in the file or global loader config.
  • Animation.setCurrentFrame will no longer try to call setOrigin or updateDisplayOrigin if the Game Object doesn't have the Origin component, preventing unknown function errors.
  • MatterTileBody now extends EventEmitter, meaning you can listen to collision events from Tiles directly and it will no longer throw errors about gameObject.emit not working. Fix #4967 (thanks @reinildo)
  • Added MatterJS.BodyType to GameObject.body type. Fix #4962 (thanks @meisterpeeps)
  • The JSONHash loader didn't load custom pivot information, but JSONArray did. So that functionality has been duplicated into the JSONHash file type (thanks @veleek)
  • When enabling a Game Object for input debug, the debug body's depth was 0. It's now set to be the same depth as the actual Game Object (thanks @mktcode)
  • Spine Files can now be loaded via a manifest, allowing you to specify a prefix in the loader object and providing absolute paths to textures. Fix #4813 (thanks @FostUK @a610569731)
  • collideSpriteVsGroup now exits early when the Sprite has checkCollision.none, skipping an unnecessary iteration of the group (thanks @samme)
  • collideSpriteVsGroup when looping through the tree results now skips bodies with checkCollision.none (thanks @samme)
  • When enabling a Game Object for Input Debugging the created debug shape will now factor in the position, scale and rotation of the Game Objects parent Container, if it has one (thanks @scott20145)

Bug Fixes

  • The conditional checking if the PathFollower was at the end of the path or not was incorrect (thanks @samme)
  • Creating an Arcade Physics Body from a scaled Game Object would use the un-scaled dimensions for the body. They now use the scaled dimensions. This may be a breaking change in some games, so please be aware of it (thanks @samme)
  • Creating an Arcade Physics Static Body from a scaled Game Object would use the un-scaled dimensions for the body. They now use the scaled dimensions. This may be a breaking change in some games, so please be aware of it (thanks @samme)
  • The Arcade Physics Static Body center was incorrect after construction. Probably caused problems with circle collisions. Fix #4770 (thanks @samme)
  • An Arcade Physics Body center and position are now correct after construction and before preUpdate(), for any Game Object origin or scale (thanks @samme)
  • When calling Body.setSize with the center parameter as true the calculated offset would be incorrect for scaled Game Objects. The offset now takes scaling into consideration (thanks @samme)
  • HTML5AudioFile.load would throw an error in strict mode (thanks @samme)
  • When using the No Audio Sound Manager, calling destroy() would cause a Maximum call stack size exceeded error as it was missing 6 setter methods. It will now destroy properly (thanks @samme)
  • When using HTML5 Audio, setting the game or sound volume outside of the range 0-1 would throw an index size error. The value is now clamped before being set (thanks @samme)
  • Sound Managers were still listening to Game BLUR, FOCUS, and PRE_STEP events after being destroyed. These events are now cleared up properly (thanks @samme)
  • In WebGL, the TextureTintPipeline is now set before rendering any camera effects. If the pipeline had been changed, the effects would not run (thanks @TroKEMp)
  • When transitioning to a sleeping Scene, the transition data wasn't sent to the Scene wake method. It's now sent across to both sleeping and waking scenes. Fix #5078 (thanks @MrMadClown)
  • Scale.lockOrientation('portrait') would throw a runtime error in Firefox: 'TypeError: 'mozLockOrientation' called on an object that does not implement interface Screen.' It no longer does this. Fix #5069 (thanks @123survesh)
  • The FILE_COMPLETE event was being emitted twice for a JSON loaded animation file. It now only fires once. Fix #5059 (thanks @jjcapellan)
  • If you restart or stop / start a scene and then queue at least one new file in preload, the scenes update function is called before create, likely causing an error. Fix #5065 (thanks @samme)
  • Circle.GetPoints will now check that stepRate is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
  • Ellipse.GetPoints will now check that stepRate is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
  • Line.GetPoints will now check that stepRate is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
  • Polygon.GetPoints will now check that stepRate is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
  • Rectangle.GetPoints will now check that stepRate is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
  • Triangle.GetPoints will now check that stepRate is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
  • Changing the game size with a scale mode of FIT resulted in a canvas with a incorrect aspect ratio. Fix #4971 (thanks @Kitsee @samme)
  • The Matter Physics Common.isString function would cause a 'TypeError: Invalid calling object' in Internet Explorer (thanks @samme)
  • Arcade.Body.checkCollision.none did not prevent collisions with Tiles. Now it does (thanks @samme)
  • When running in HEADLESS mode, using a Text Game Object would cause a runtime error "Cannot read property gl of null". Fix #4976 (thanks @raimon-segura @samme)
  • The Tilemap LayerData class properties property has been changed from 'object' to an array of objects, which is what Tiled exports when defining layer properties in the editor. Fix #4983 (thanks @Nightspeller)
  • AudioFile and VideoFile had their state set to undefined instead of FILE_PROCESSING (thanks @samme)
  • Container.getBounds would return incorrect values if it had child Containers within it. Fix #4580 (thanks @Minious @thedrint)
  • The Loader no longer prepends the current path to the URL if it's a Blob object (thanks @aucguy)
  • Spine Atlases can now be loaded correctly via Asset Packs, as they now have the right index applied to them (thanks @jdcook)
  • Input events for children inside nested Containers would incorrectly fire depending on the pointer position (thanks @rexrainbow)
  • Animations with both yoyo and repeatDelay set will respect the delay after each yoyo runs (thanks @cruzdanilo)
  • CanvasTexture.setSize forgot to update the width and height properties of the Texture itself. These now match the underlying canvas element. Fix #5054 (thanks @sebbernery)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@JasonHK @supertommy @majalon @samme @MartinBlackburn @halilcakar @jcyuan @MrMadClown @Dinozor @EmilSV @Jazcash

- JavaScript
Published by photonstorm about 6 years ago

phaser - Phaser v3.22.0

Matter Physics

All of the following are specific to the Matter Physics implementation used by Phaser:

Matter Physics New Features

  • Matter Physics now has 100% JSDoc coverage! Woohoo :)
  • Matter Physics now has brand new TypeScript defs included in the types folder :)
  • MatterDebugConfig is a new configuration object that contains all of the following new Matter debug settings:
  • showAxes- Render all of the body axes?
  • showAngleIndicator- Render just a single body axis?
  • angleColor- The color of the body angle / axes lines.
  • showBroadphase- Render the broadphase grid?
  • broadphaseColor- The color of the broadphase grid.
  • showBounds- Render the bounds of the bodies in the world?
  • boundsColor- The color of the body bounds.
  • showVelocity- Render the velocity of the bodies in the world?
  • velocityColor- The color of the body velocity line.
  • showCollisions- Render the collision points and normals for colliding pairs.
  • collisionColor- The color of the collision points.
  • showSeparation- Render lines showing the separation between bodies.
  • separationColor- The color of the body separation line.
  • showBody- Render the dynamic bodies in the world to the Graphics object?
  • showStaticBody- Render the static bodies in the world to the Graphics object?
  • showInternalEdges- When rendering bodies, render the internal edges as well?
  • renderFill- Render the bodies using a fill color.
  • renderLine- Render the bodies using a line stroke.
  • fillColor- The color value of the fill when rendering dynamic bodies.
  • fillOpacity- The opacity of the fill when rendering dynamic bodies, a value between 0 and 1.
  • lineColor- The color value of the line stroke when rendering dynamic bodies.
  • lineOpacity- The opacity of the line when rendering dynamic bodies, a value between 0 and 1.
  • lineThickness- If rendering lines, the thickness of the line.
  • staticFillColor- The color value of the fill when rendering static bodies.
  • staticLineColor- The color value of the line stroke when rendering static bodies.
  • showSleeping- Render any sleeping bodies (dynamic or static) in the world to the Graphics object?
  • staticBodySleepOpacity] - The amount to multiply the opacity of sleeping static bodies by.
  • sleepFillColor- The color value of the fill when rendering sleeping dynamic bodies.
  • sleepLineColor- The color value of the line stroke when rendering sleeping dynamic bodies.
  • showSensors- Render bodies or body parts that are flagged as being a sensor?
  • sensorFillColor- The fill color when rendering body sensors.
  • sensorLineColor- The line color when rendering body sensors.
  • showPositions- Render the position of non-static bodies?
  • positionSize- The size of the rectangle drawn when rendering the body position.
  • positionColor- The color value of the rectangle drawn when rendering the body position.
  • showJoint- Render all world constraints to the Graphics object?
  • jointColor- The color value of joints when showJoint is set.
  • jointLineOpacity- The line opacity when rendering joints, a value between 0 and 1.
  • jointLineThickness- The line thickness when rendering joints.
  • pinSize- The size of the circles drawn when rendering pin constraints.
  • pinColor- The color value of the circles drawn when rendering pin constraints.
  • springColor- The color value of spring constraints.
  • anchorColor- The color value of constraint anchors.
  • anchorSize- The size of the circles drawn as the constraint anchors.
  • showConvexHulls- When rendering polygon bodies, render the convex hull as well?
  • hullColor- The color value of hulls when showConvexHulls is set.
  • World.renderBody is a new method that will render a single Matter Body to the given Graphics object. This is used internally during debug rendering but is also public. This allows you to control which bodies are rendered and to which Graphics object, should you wish to use them in-game and not just during debugging.
  • World.renderConstraint is a new method that will render a single Matter Constraint, such as a pin or a spring, to the given Graphics object. This is used internally during debug rendering but is also public. This allows you to control which constraints are rendered and to which Graphics object, should you wish to use them in-game and not just during debugging.
  • World.renderConvexHull is a new method that will render the convex hull of a single Matter Body, to the given Graphics object. This is used internally during debug rendering but is also public. This allows you to control which hulls are rendered and to which Graphics object, should you wish to use them in-game and not just during debugging.
  • World.renderGrid is a new method that will render the broadphase Grid to the given graphics instance.
  • World.renderBodyBounds is a new method that will render the bounds of all the given bodies to the given graphics instance.
  • World.renderBodyAxes is a new method that will render the axes of all the given bodies to the given graphics instance.
  • World.renderBodyVelocity is a new method that will render a velocity line for all the given bodies to the given graphics instance.
  • World.renderSeparations is a new method that will render the separations in the current pairs list to the given graphics instance.
  • World.renderCollisions is a new method that will render the collision points and normals in the current pairs list to the given graphics instance.
  • World.getAllBodies is a new method that will return all bodies in the Matter World.
  • World.getAllConstraints is a new method that will return all constraints in the Matter World.
  • World.getAllComposites is a new method that will return all composites in the Matter World.
  • MatterPhysics.composite is a new reference to the Matter.Composite module for easy access from within a Scene.
  • MatterPhysics.detector is a new reference to the Matter.Dectector module for easy access from within a Scene.
  • MatterPhysics.grid is a new reference to the Matter.Grid module for easy access from within a Scene.
  • MatterPhysics.pair is a new reference to the Matter.Pair module for easy access from within a Scene.
  • MatterPhysics.pairs is a new reference to the Matter.Pairs module for easy access from within a Scene.
  • MatterPhysics.query is a new reference to the Matter.Query module for easy access from within a Scene.
  • MatterPhysics.resolver is a new reference to the Matter.Resolver module for easy access from within a Scene.
  • MatterPhysics.sat is a new reference to the Matter.SAT module for easy access from within a Scene.
  • MatterPhysics.constraint is a new reference to the Matter.Constraint module for easy access from within a Scene.
  • MatterPhysics.composites is a new reference to the Matter.Composites module for easy access from within a Scene.
  • MatterPhysics.axes is a new reference to the Matter.Axes module for easy access from within a Scene.
  • MatterPhysics.bounds is a new reference to the Matter.Bounds module for easy access from within a Scene.
  • MatterPhysics.svg is a new reference to the Matter.Svg module for easy access from within a Scene.
  • MatterPhysics.vector is a new reference to the Matter.Vector module for easy access from within a Scene.
  • MatterPhysics.vertices is a new reference to the Matter.Vertices module for easy access from within a Scene.
  • BEFORE_ADD is a new Event dispatched by Matter.World when a Body or Constraint is about to be added to the World.
  • AFTER_ADD is a new Event dispatched by Matter.World when a Body or Constraint has been added to the World.
  • BEFORE_REMOVE is a new Event dispatched by Matter.World when a Body or Constraint is about to be removed from the World.
  • AFTER_REMOVE is a new Event dispatched by Matter.World when a Body or Constraint has been removed from the World.
  • Body.render.lineOpacity is a new property on the Matter Body object that allows for custom debug rendering.
  • Body.render.lineThickness is a new property on the Matter Body object that allows for custom debug rendering.
  • Body.render.fillOpacity is a new property on the Matter Body object that allows for custom debug rendering.
  • World.setCompositeRenderStyle is a new method that lets you quickly set the render style values on the children of the given compposite.
  • World.setBodyRenderStyle is a new method that lets you quickly set the render style values on the given Body.
  • World.setConstraintRenderStyle is a new method that lets you quickly set the render style values on the given Constraint.
  • You can now set restingThresh in the Matter Configuration file to adjust the Resolver property.
  • You can now set restingThreshTangent in the Matter Configuration file to adjust the Resolver property.
  • You can now set positionDampen in the Matter Configuration file to adjust the Resolver property.
  • You can now set positionWarming in the Matter Configuration file to adjust the Resolver property.
  • You can now set frictionNormalMultiplier in the Matter Configuration file to adjust the Resolver property.
  • MatterPhysics.containsPoint is a new method that returns a boolean if any of the given bodies intersect with the given point.
  • MatterPhysics.intersectPoint is a new method that checks which bodies intersect with the given point and returns them.
  • MatterPhysics.intersectRect is a new method that checks which bodies intersect with the given rectangular area, and returns them. Optionally, it can check which bodies are outside of the area.
  • MatterPhysics.intersectRay is a new method that checks which bodies intersect with the given ray segment and returns them. Optionally, you can set the width of the ray.
  • MatterPhysics.intersectBody is a new method that checks which bodies intersect with the given body and returns them. If the bodies are set to not collide this can be used as an overlaps check.
  • MatterPhysics.overlap is a new method that takes a target body and checks to see if it overlaps with any of the bodies given. If they do, optional process and overlap callbacks are invoked, passing the overlapping bodies to them, along with additional collision data.
  • MatterPhysics.setCollisionCategory is a new method that will set the collision filter category to the value given, on all of the bodies given. This allows you to easily set the category on bodies that don't have a Phaser Matter Collision component.
  • MatterPhysics.setCollisionGroup is a new method that will set the collision filter group to the value given, on all of the bodies given. This allows you to easily set the group on bodies that don't have a Phaser Matter Collision component.
  • MatterPhysics.setCollidesWith is a new method that will set the collision filter mask to the value given, on all of the bodies given. This allows you to easily set the filter mask on bodies that don't have a Phaser Matter Collision component.
  • Matter.Body.centerOfMass is a new vec2 property added to the Matter Body object that retains the center of mass coordinates when the Body is first created, or has parts added to it. These are float values, derived from the body position and bounds.
  • Matter.Body.centerOffset is a new vec2 property added to the Matter Body object that retains the center offset coordinates when the Body is first created, or has parts added to it. These are pixel values.
  • Constraint.pointAWorld is a new method added to Matter that returns the world-space position of constraint.pointA, accounting for constraint.bodyA.
  • Constraint.pointBWorld is a new method added to Matter that returns the world-space position of constraint.pointB, accounting for constraint.bodyB.
  • Body.setCentre is a new method added to Matter that allows you to set the center of mass of a Body (please note the English spelling of this function.)
  • Body.scale is a new read-only vector that holds the most recent scale values as passed to Body.scale.
  • Matter.Bodies.flagCoincidentParts is a new function that will flags all internal edges (coincident parts) on an array of body parts. This was previously part of the fromVertices function, but has been made external for outside use.
  • Matter.getMatterBodies is a new function that will return an array of Matter JS Bodies from the given input array, which can be Matter Game Objects, or any class that extends them.
  • Matter.World.has is a new method that will take a Matter Body, or Game Object, and search the world for it. If found, it will return true.
  • Matter now has the option to use the Runner that it ships with. The Matter Runner operates in two modes: fixed and variable. In the fixed mode, the Matter Engine updates at a fixed delta value every frame (which is what Phaser has used since the first version). In variable mode, the delta will be smoothed and capped each frame to keep the simulation constant, but at the cost of determininism. You can configure the runner by setting the runner property in the Matter Config object, both of which are fully covered with JSDocs. As of 3.22 the runner is now used by default in variable (non-fixed) mode. If you wish to return to the previous behavior, set runner: { isFixed: true }.
  • Body.onCollideCallback is a new Matter Body property that can point to a callback to invoke when the body starts colliding.
  • Body.onCollideEndCallback is a new Matter Body property that can point to a callback to invoke when the body stops colliding.
  • Body.onCollideActiveCallback is a new Matter Body property that can point to a callback to invoke for the duration the body is colliding.
  • Body.onCollideWith is a new Matter Body property that holds a mapping between bodies and collision callbacks.
  • MatterGameObject.setOnCollide is a new method available on any Matter Game Object, that sets a callback that is invoked when the body collides with another.
  • MatterGameObject.setOnCollideEnd is a new method available on any Matter Game Object, that sets a callback that is invoked when the body stops colliding.
  • MatterGameObject.setOnCollideActive is a new method available on any Matter Game Object, that sets a callback which is invoked for the duration of the bodies collision with another.
  • MatterGameObject.setOnCollideWith is a new method available on any Matter Game Object, that allows you to set a callback to be invoked whenever the body collides with another specific body, or array of bodies.
  • Body.gravityScale is a new vector property that allows you to scale the effect of world gravity on a specific Body.
  • MatterPhysics._tempVec2 is a new private internal vector used for velocity and force calculations.
  • MatterPhysics.setVelocity is a new method that will set both the horizontal and vertical linear velocity of the given physics bodies. This can be used on all Matter bodies, not just those created via the factory.
  • MatterPhysics.setVelocityX is a new method that will set the horizontal linear velocity of the given physics bodies. This can be used on all Matter bodies, not just those created via the factory.
  • MatterPhysics.setVelocityY is a new method that will set the vertical linear velocity of the given physics bodies. This can be used on all Matter bodies, not just those created via the factory.
  • MatterPhysics.setAngularVelocity is a new method that will set the angular velocity of the given physics bodies. This can be used on all Matter bodies, not just those created via the factory.
  • MatterPhysics.applyForce is a new method that applies a force to a body, at the bodies current position, including resulting torque. This can be used on all Matter bodies, not just those created via the factory.
  • MatterPhysics.applyForceFromPosition is a new method that 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. This can be used on all Matter bodies, not just those created via the factory.
  • MatterPhysics.fromSVG is a new method that allows you to create a Body from the given SVG path data.
  • The Matter.Factory.velocity method has been removed. Please now use MatterPhysics.setVelocity instead.
  • The Matter.Factory.angularVelocity method has been removed. Please now use MatterPhysics.setAngularVelocity instead.
  • The Matter.Factory.force method has been removed. Please now use MatterPhysics.applyForce instead.
  • MatterBodyConfig is a new type def that contains all of the Body configuration properties. This is now used through-out the JSDocs to aid in code-completion.
  • MatterBodyRenderConfig is a new type def that contains all of the Body debug rendering configuration properties. This is now used through-out the JSDocs to aid in code-completion.
  • MatterChamferConfig is a new type def that contains all of the chamfer configuration properties. This is now used through-out the JSDocs to aid in code-completion.
  • MatterCollisionFilter is a new type def that contains all of the collision configuration properties. This is now used through-out the JSDocs to aid in code-completion.
  • MatterConstraintConfig is a new type def that contains all of the constraint configuration properties. This is now used through-out the JSDocs to aid in code-completion.
  • MatterConstraintRenderConfig is a new type def that contains all of the Constraint debug rendering configuration properties. This is now used through-out the JSDocs to aid in code-completion.
  • MatterSetBodyConfig is a new type def that contains all of the Constraint debug rendering configuration properties. This is now used through-out the JSDocs to aid in code-completion.
  • MatterPhysics.getConstraintLength is a new method that will return the length of the given constraint, as this is something you cannot get from the constraint properties directly.
  • MatterPhysics.alignBody is a new method that will align a Body, or Matter Game Object, against the given coordinates, using the given alignment constant. For example, this allows you to easily position a body to the BOTTOM_LEFT, or TOP_CENTER, or a coordinate. Alignment is based on the body bounds.
  • Phaser.Types.Physics.Matter.MatterBody is a new type def that contains all of the valid Matter Body objects. This is now used through-out the JSDocs to aid in code-completion.
  • Matter.BodyBounds is a new class that contains methods to help you extract world coordinates from various points around the bounds of a Matter Body. Because Matter bodies are positioned based on their center of mass, and not a dimension based center, you often need to get the bounds coordinates in order to properly align them in the world. You can access this new class via this.matter.bodyBounds.
  • The method signature for Matter.PhysicsEditorParser.parseBody has changed. It now takes (x, y, config, options) and no longer has width and height parameters. Please see the updated documentation for more details if you were calling this method directly.
  • MatterPhysics.fromPhysicsEditor is a new method that allows you to create a Matter Body based on the given PhysicsEditor shape data. Previously, you could only using PhysicsEditor data with a Matter Game Object, but now you can create a body directly using it.
  • Matter.PhysicsJSONParser is a new parser that will create Matter bodies from JSON physics data files. Currently onto the Phaser Physics Tracer app exports in this format, but details are published in the JSDocs, so any app can do so.
  • Matter.Factory.fromJSON is a new method that will create a body from a JSON physics data file.
  • The SetBody Matter component can now automatically use shapes created in the Phaser Physics Tracer App in the JSON data format.
  • Matter.Components.Sleep.setToSleep is a new method available on any Matter Game Object that will send the body to sleep, if Engine sleeping has been enabled.
  • Matter.Components.Sleep.setAwake is a new method available on any Matter Game Object that will awake a body from sleep, if Engine sleeping has been enabled.

Matter Physics Updates

  • The debug property in the Matter World Config is now a MatterDebugConfig option instead of a boolean. However, if a boolean is given, it will use the default debug config values.
  • The following MatterWorldConfig options have now been removed: debugShowBody, debugShowStaticBody, debugBodyColor, debugBodyFillColor, debugStaticBodyColor, debugShowJoint, debugJointColor, debugWireframes, debugShowInternalEdges, debugShowConvexHulls, debugConvexHullColor and debugShowSleeping. These can all be set via the new MatterDebugConfig object instead.
  • The object World.defaults has been removed. Defaults are now access via World.debugDefaults.
  • World.renderBodies has been rewritten to cache commonly-used values and avoid a situation when a single body would be rendered twice.
  • The private method World.renderConvexHulls has been removed as it's no longer used internally.
  • The private method World.renderWireframes has been removed as it's no longer used internally.
  • The method World.fromPath has been removed. This was never used internally and you can get the same results by calling Vertices.fromPath.
  • The World.setBounds argument thickness now defaults to 64, not 128, to keep it matching the Matter World Config.
  • The Body.render.fillStyle property that existed on the Matter Body object has been removed and replaced with fillColor.
  • The Body.render.strokeStyle property that existed on the Matter Body object has been removed and replaced with lineColor.
  • Matter.Body.render.sprite.xOffset and yOffset are no longer set to anything when a Body is created. They are left as zero, or you can override them in the Body config, in which case the value is added to the sprite origin offset during a call to setExistingBody.
  • The Matter.Mass.centerOfMass component property now returns the pre-calculated Body centerOfMass property, which is much more accurate than the previous bounds offset value.
  • Matter.setExistingBody, which is called interally whenever a Body is set on a Game Object, now uses the new centerOffset values to ensure that the texture frame is correctly centered based on the center of mass, not the Body bounds, allowing for much more accurate body to texture mapping with complex multi-part compound bodies.
  • The Matter.PhysicsEditorParser has been updated so it no longer needs to set the render offsets, and instead uses the center of mass values.
  • If the Matter.Body config doesn't contain a position property, it will now default to using Vertices.centre(body.vertices) as the position. In most cases, this is what you need, so it saves having to pass it in the config object.
  • Bumped Matter Plugin versions to avoid console logs from Common.info and Common.warn.
  • PhysicsEditorParser.parseVertices now uses Bodies.flagCoincidentParts to avoid duplicating code.
  • MatterGameObject has a new optional boolean constructor parameter addToWorld which lets you control if the Body should be added to the world or not. Useful for toggling off should you be merging pre-existing bodies with Game Objects.
  • The Matter.SetBody.setExistingBody function, which all Matter Game Objects have, has a new parameter addToWorld which allows you to control when the body is added to the Matter world should you not require it immediately. It will also only add the body to the world if it doesn't already exist within it, or any of its composites.
  • PointerConstraint has been recoded so that when pressed down, it only polls the World for a body hit test during the next game update. This stops it coming out of sync with the state of the world. Use of the constraint remains the same as before.
  • You can now set gravity: false in your Matter Config and it will reset gravity from the defaults to zero.
  • The internal Matter Composite.setModified function will now emit a compositeModified event, which the Matter World listens for, if debug draw is enabled, so it can update the composite children render styles.
  • Matter.PhysicsEditorParser.parseBody can now accept a MatterBodyConfig file as a 4th parameter. This allows you to set Body properties when the body is created, overriding whatever values may have been set in the PhysicsEditor JSON.

Matter Physics Bug Fixes

  • Due to the rewrite of the debug rendering, it is now possible to render just constraints, where-as before this was only possible if bodies were being rendered as well. Fix #4880 (thanks @roberto257)
  • Matter.PhysicsEditorParser had a bug where it would allow fixtures with non-clockwise sorted vertices through, which would break pointer constraint interaction with these bodies. The parser now sorts the vertices properly. Fix #4261 (thanks @Sanchez3)

New Features

  • TimeStep.smoothStep is a new boolean property that controls if any delta smoothing takes place during the game step. Delta smoothing has been enabled in Phaser since the first version and helps avoid delta spikes and dips, especially after loss of focus. However, you can now easily toggle if this happens via this property and the corresponding FPSConfig property.
  • Phaser.Math.Distance.BetweenPoints is a new function that will return the distance between two Vector2-like objects (thanks @samme)
  • Phaser.Math.Distance.BetweenPointsSquared is a new function that will return the squared distance between two Vector2-like objects (thanks @samme)
  • Phaser.Math.Distance.Chebyshev is a new function that will return the Chebyshev (or chessboard) distance between two Vector2-like objects (thanks @samme)
  • Phaser.Math.Distance.Snake is a new function that will return the rectilinear distance between two Vector2-like objects (thanks @samme)
  • ParticleEmitter.setTint is a new method that will set the tint of emitted particles for the given Emitter only (thanks @samme)
  • ParticleEmitter.remove is a new method that will remove the Emitter from its Emitter Manager (thanks @samme)
  • ParticleEmitterManager.removeEmitter is a new method that will remove the given emitter from the manager, if the emitter belongs to it (thanks @samme)
  • AlphaSingle is a new Game Object Component that allows a Game Object to set its alpha values, but only as a single uniform value, not on a per-quad basis.
  • Actions.AlignTo (in combination with the new Display.Align.To.QuickSet function) allows you to align an array of Game Objects so they sit next to each other, one at a time. The first item isn't moved, the second is moved to sit next to the first, and so on. You can align them using any of the alignment constants (thanks @samme)
  • Scene.Systems.getData is a new method that will return any data that was sent to the Scene by another Scene, i.e. during a run or launch command. You can access it via this.sys.getData() from within your Scene.
  • Group.internalCreateCallback is a new optional callback that is invoked whenever a child is added to a Group. This is the same as createCallback except it's only for use by the parent class, allowing a parent to invoke a creation callback and for you to still provide one via the Group config.
  • Group.internalRemoveCallback is a new optional callback that is invoked whenever a child is removed from a Group. This is the same as removeCallback except it's only for use by the parent class, allowing a parent to invoke a callback and for you to still provide one via the Group config.

Updates

  • Body.deltaXFinal is a new method on Arcade Physics Bodies that will return the final change in the horizontal position of the body, as based on all the steps that took place this frame. This property is calculated during the postUpdate phase, so must be listened for accordingly (thanks Bambosh)
  • Body.deltaYFinal is a new method on Arcade Physics Bodies that will return the final change in the vertical position of the body, as based on all the steps that took place this frame. This property is calculated during the postUpdate phase, so must be listened for accordingly (thanks Bambosh)
  • Body._tx is a new internal private var, holding the Arcade Physics Body combined total delta x value.
  • Body._ty is a new internal private var, holding the Arcade Physics Body combined total delta y value.
  • LineCurve.getUtoTmapping has been updated to return u directly to avoid calculations as it's identical to t in a Line (thanks @rexrainbow)
  • Curve.getSpacedPoints will now take an optional array as the 3rd parameter to store the points results in (thanks @rexrainbow)
  • Trying to play or resume an audio file with an incorrect key will now throw a runtime error, instead of a console warning (thanks @samme)
  • The Shape Game Object now uses the AlphaSingle component, allowing you to uniformly set the alpha of the shape, rather than a quad alpha, which never worked for Shape objects.
  • The Container Game Object now uses the AlphaSingle component, allowing you to uniformly set the alpha of the container, rather than a quad alpha, which never worked consistently across Container children. Fix #4916 (thanks @laineus)
  • The DOMElement Game Object now uses the AlphaSingle component, allowing you to uniformly set the alpha of the element, rather than a quad alpha, which never worked for these objects.
  • The Graphics Game Object now uses the AlphaSingle component, allowing you to uniformly set the alpha of the element, rather than a quad alpha, which never worked for these objects.
  • TweenData has a new property called previous which holds the eased property value prior to the update.
  • The TWEEN_UPDATE event now sends two new parameters to the handler: current and previous which contain the current and previous property values.
  • During collideSpriteVsGroup checks it will now skip bodies that are disabled to save doing a contains test (thanks @samme)
  • Display.Align.In.QuickSet now accepts LEFT_BOTTOM as BOTTOM_LEFT, LEFT_TOP as TOP_LEFT, RIGHT_BOTTOM as BOTTOM_RIGHT and RIGHT_TOP as TOP_RIGHT. Fix #4927 (thanks @zaniar)
  • PhysicsGroup now uses the new internalCreateCallback and internalRemoveCallback to handle its body creation and destruction, allowing you to use your own createCallback and removeCallback as defined in the Group config. Fix #4420 #4657 #4822 (thanks @S4n60w3n @kendistiller @scrubperson)
  • DOMElement has a new private method handleSceneEvent which will handle toggling the display setting of the element when a Scene sleeps and wakes. A DOM Element will now listen for the Scene sleep and wake events. These event listeners are removed in the preDestroy method.
  • A DOMElement will now set the display mode to 'none' during its render if the Scene in which it belongs is no longer visible.

Bug Fixes

  • BitmapText with a maxWidth set wouldn't update the text correctly if it was modified post-creation. You can now update the text and/or width independantly and it'll update correctly. Fix #4881 (thanks @oxguy3)
  • Text objects will no longer add any white-space when word-wrapping if the last line is only one word long. Fix #4867 (thanks @gaamoo @rexrainbow)
  • When Game.destroy is running, Scenes are now destroyed before plugins, avoiding bugs when closing down plugins and deleting Render Textures. Fix #4849 #4876 (thanks @rexrainbow @siyuanqiao)
  • The Mesh and Quad Game Objects have had the GetBounds component removed as it cannot operate on a Mesh as they don't have origins. Fix #4902 (thanks @samme)
  • Setting lineSpacing in the Text Game Object style config would set the value but not apply it to the Text, leaving you to call updateText yourself. If set, it's now applied on instantiation. Fix #4901 (thanks @FantaZZ)
  • External calls to the Fullscreen API using element.requestFullscreen() would be blocked by the Scale Manager. The Scale Manager will no longer call stopFullScreen should it be triggered outside of Phaser (thanks @AdamXA)
  • The Tilemaps.Tile.tint property wasn't working correctly as it expected the colors in the wrong order (BGR instead of RGB). It will now expect them in the correct RGB order (thanks @Aedalus @plissken2013es)
  • The ScaleManager.destroy method wasn't being called when the Game DESTROY event was dispatched, causing minor gc to build up. The destroy method will now be called properly on game destruction. Fix #4944 (thanks @sunshineuoow)
  • FacebookInstantGamesPlugin.showAd and showVideo will now break out of the ad iteration search once a valid ad has been found and called. Previously, it would carry on interating if the async didn't complete quickly. Fix #4888 (thanks @east62687)
  • When playing an Animation, if you were to play another, then pause it, then play another the internal _paused wouldn't get reset, preventing you from them pausing the animations from that point on. You can now play and pause animations at will. Fix #4835 (thanks @murteira)
  • In Actions.GridAlign if you set width to -1 it would align the items vertically, instead of horizontally. It now aligns them horizontally if width is set, or vertically if height is set. Fix #4899 (thanks @BenjaVR)
  • A PathFollower with a very short duration would often not end in the correct place, which is the very end of the Path, due to the tween handling the movement not running one final update when the tween was complete. It will now always end at the final point of the path, no matter how short the duration. Fix #4950 (thanks @bramp)
  • A DOMElement would still remain visible even if the Scene in which it belongs to was sent to sleep. A sleeping Scene shouldn't render anything. DOM Elements will now respond to sleep and wake events from their parent Scene. Fix #4870 (thanks @peonmodel)
  • If a config object was passed to MultiAtlasFile it expected the atlas URL to be in the url property, however the docs and file config expected it in atlasURL. You can now use either of these properties to declare the url. Fix #4815 (thanks @xense)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@fselcukcan Bambosh @louisth @hexus @javigaralva @samme @BeLi4L @jcyuan @javigaralva @T-Grave @bramp @Chnapy @dranitski @RollinSafary @xense

The Matter TypeScript defs have been updated to include lots of missing classes, removed some redundant elements and general fixes. The Phaser TypeScript defs now reference the Matter defs directly and no longer try to parse them from the JSDocs. This allows the MatterJS namespace to work in TypeScript projects without any compilation warnings.

The Spine Plugin now has new TypeScript defs in the types folder thanks to @supertommy

- JavaScript
Published by photonstorm over 6 years ago

phaser - Phaser v3.21.0

New Features

  • You can now specify the mipmap filter level to be used when creating WebGL textures. This can be set in the Game Config using the new mipmapFilter property, which is a string, such as 'NEARESTMIPMAPNEAREST'. Or, you can set the new WebGLRenderer.mipmapFilter property to a valid GLenum. If you set it on the renderer, it will only impact any textures loaded after it has been set, so do so in your Scene init method if you want it to be used for textures you're about to load. By changing the mipmap level you can drastically improve the quality when reducing large textures. Please note, due to WebGL1 limitations, this only works on power-of-two sized textures. It also works on textures created from Canvas, Videos or RenderTextures.
  • BitmapText.setMaxWidth is a new method that allows you to set a maximum width (in pixels) for the BitmapText to take up when rendering. Lines of text longer than maxWidth will be wrapped, based on whitespace, to the next line. This allows you to do word-wrapping on BitmapText objects, something only previously possible on Text objects.
  • BitmapText.wordWrapCharCode is a new property that works with setMaxWidth that allows you to control which character code causes a line-wrap. By default it is 32 (a space character).
  • ArcadePhysics.closest now has an optional targets argument. The targets can be any Arcade Physics Game Object, Body or Static Body and it will return only the closet target from those given (thanks @samme)
  • ArcadePhysics.furthest now has an optional targets argument. The targets can be any Arcade Physics Game Object, Body or Static Body and it will return only the furthest target from those given (thanks @samme)
  • Tilemaps.Parsers.Tiled.CreateGroupLayer is a new function that parses a Tiled group layer and adds in support for Tiled layer groups (introduced in Tiled 1.2.0). Feature #4099 (thanks @Babeetlebum @Olliebrown)
  • The Tilemap system now supports infinite Tilemaps from the Tiled map editor (thanks @Olliebrown)
  • Tilemap.getImageLayerNames is a new method that returns a list of all valid imagelayer names loaded in the Tilemap (thanks @Olliebrown)
  • Tilemap.getObjectLayerNames is a new method that returns a list of all valid objectgroup names loaded in the Tilemap (thanks @Olliebrown)
  • Tilemap.getTileLayerNames is a new method that returns a list of all valid tilelayer names loaded in the Tilemap (thanks @Olliebrown)
  • When forceSetTimeOut is set to true in the Game Config, you can now set the target frame rate by setting the fps.target value (thanks @pavels)
  • Videos can now be loaded from a data URI, allowing for base64 encoded videos to be used in the Loader instead of file based ones. Although, as with all base64 encoded data, we strongly recommend against this (thanks @apasov)
  • Math.MIN_SAFE_INTEGER is a new math const that stores the minimum safe integer for browsers that don't provide this, such as IE (thanks @jronn)
  • Math.MAX_SAFE_INTEGER is a new math const that stores the maximum safe integer for browsers that don't provide this, such as IE (thanks @jronn)
  • KeyCodes.NUMPAD_ADD has been added to the keycodes list (thanks @Martin-Antonov)
  • KeyCodes.NUMPAD_SUBTRACT has been added to the keycodes list (thanks @Martin-Antonov)
  • Video.removeVideoElementOnDestroy is a new boolean property that allows you to control if the Video element is removed from the DOM when the Video Game Object is destroyed.
  • Actions.SetScrollFactor is a new Action that will set the scroll factor on an array of Game Objects, including stepped incremental changes per item (thanks @rexrainbow)
  • Actions.SetScrollFactorX is a new Action that will set the horizontal scroll factor on an array of Game Objects, including stepped incremental changes per item (thanks @rexrainbow)
  • Actions.SetScrollFactorY is a new Action that will set the horizontal scroll factor on an array of Game Objects, including stepped incremental changes per item (thanks @rexrainbow)
  • The Group config object now supports use of the setScrollFactor property to set the value on each child of the Group (thanks @rexrainbow)
  • Group.propertyValueSet is a new method that sets a given property on each Group member (thanks @rexrainbow)
  • Group.propertyValueInc is a new method that adds an amount to a given property on each Group member (thanks @rexrainbow)
  • Group.setX is a new method that sets the x coordinate on each Group member (thanks @rexrainbow)
  • Group.setY is a new method that sets the y coordinate on each Group member (thanks @rexrainbow)
  • Group.setXY is a new method that sets the x and y coordinate on each Group member (thanks @rexrainbow)
  • Group.incX is a new method that increments the x coordinate on each Group member (thanks @rexrainbow)
  • Group.incY is a new method that increments the y coordinate on each Group member (thanks @rexrainbow)
  • Group.incXY is a new method that increments the x and y coordinate on each Group member (thanks @rexrainbow)
  • Group.shiftPosition is a new method that iterates the Group members and shifts the position of each to the previous members position (thanks @rexrainbow)
  • Group.angle is a new method that sets the angle property on each Group member (thanks @rexrainbow)
  • Group.rotate is a new method that sets the rotation property on each Group member (thanks @rexrainbow)
  • Group.rotateAround is a new method that rotates each Group member around the given point, by the given angle (thanks @rexrainbow)
  • Group.rotateAroundDistance is a new method that rotates each Group member around the given point, by the given angle and distance (thanks @rexrainbow)
  • Group.setAlpha is a new method that sets the alpha property on each Group member (thanks @rexrainbow)
  • Group.setTint is a new method that sets the tint property on each Group member (thanks @rexrainbow)
  • Group.setOrigin is a new method that sets the origin property on each Group member (thanks @rexrainbow)
  • Group.scaleX is a new method that sets the x scale on each Group member (thanks @rexrainbow)
  • Group.scaleY is a new method that sets the y scale on each Group member (thanks @rexrainbow)
  • Group.scaleXY is a new method that sets the x and y scale on each Group member (thanks @rexrainbow)
  • Group.setBlendMode is a new method that sets the blend mode on each Group member (thanks @rexrainbow)
  • Group.setHitArea is a new method that passes all Group members to the Input Plugin to enable them for input (thanks @rexrainbow)
  • Group.shuffle is a new method that shuffles all of the Group members in place (thanks @rexrainbow)
  • Group.setVisible is a new method that sets the visible state on each Group member (thanks @rexrainbow)
  • WebAudioSoundManager.setAudioContext is a new method that allows you to set the Sound Manager Audio Context to a different context instance. It will also disconnect and re-create the gain nodes on the new context.
  • Group.type is a new property that holds a string-based name of the Game Object type, as with other GO's (thanks @samme)
  • Arade.Group.type is a new property that holds a string-based name of the Game Object type, as with other GO's (thanks @samme)
  • Arcade.StaticGroup.type is a new property that holds a string-based name of the Game Object type, as with other GO's (thanks @samme)
  • ArcadePhysics.overlapCirc is a new method that allows you to return an array of all Arcade Physics bodies that overlap with the given circular area of the world. It can return either dynamic or static bodies, or a mixture of both (thanks @samme)

Updates

  • Curve.getPoints can now take an optional array as the 3rd parameter in which to store the points results (thanks @rexrainbow)
  • Line.arcLengthDivisions now overrides the default Curve value and is set to 1 to optimize the amount of points returned for a Line curve (thanks @rexrainbow)
  • ArcadePhysics.closest will now no longer ever return the source in the target results (thanks @samme)
  • ArcadePhysics.furthest will now no longer ever return the source in the target results (thanks @samme)
  • RequestAnimationFrame.target is a new property that controls the fps rate (in ms) when setTimeout is used (thanks @pavels)
  • The WebAudioSoundManager.unlock method will now listen for keydown events in order to unlock the Audio Context, as well as touch and pointer events, making it more accessible (thanks Nick Tipping)
  • The requestAnimationFrame polyfill no longer expects a Browserify environment and uses window through-out, it also no longer adds in the same as performance.now does.
  • BitmapText.getTextBounds didn't reset the dirty flag, causing the GetBitmapTextSize function to be called every time the Bitmap Text was rendered. With enough text objects on-screen this could negatively impact performance. The flag is now reset every time the bounds are recalculated.

Bug Fixes

  • The Spine Plugin was not clearing down the resize event listener in WebGL, causing it to still fire even if the Scene was closed. Fix #4808 (thanks @RollinSafary)
  • When a game is created with the HEADLESS renderer, Game.destroy() had no effect and the game kept on running. Now it destroys itself properly. Fix #4804 (thanks @samme)
  • DOM.GetScreenOrientation was returning the wrong consts from the Scale Manager (thanks @jcyuan)
  • When using Input.enableDebug on Game Objects it would not render the debug graphic correctly if the hit area had been offset. It now adjusts the debug correctly for all common hit-area geometry types. Fix #4722 (thanks @HaoboZ @Olliebrown)
  • Light2D was not properly working for DynamicTilemapLayers due to a change in the way tilesets were stored, throwing an Uncaught TypeError at runtime. This is now handled correctly. Fix #4167 #4079 (thanks @koljakutschera @blackjack26 @kainage)
  • Input.dragDistanceThreshold was not working correctly since 3.18, snapping to the wrong drag state unless the time threshold was also set. Fix #4667 (thanks @muliawanw @Olliebrown)
  • Tilemap.convertLayerToStatic would throw an error when used multiple times, due to an error with the layer index count. Fix #4737 (thanks @Olliebrown @Vegita2)
  • The Tween class now uses a cached MAXSAFEINTEGER making it compatible with Internet Explorer (thanks @jronn)
  • The StaggerBuilder class now uses a cached MAXSAFEINTEGER making it compatible with Internet Explorer (thanks @jronn)
  • The Rectangle.FromPoints function now uses a cached MINSAFEINTEGER making it compatible with Internet Explorer (thanks @jronn)
  • The Video class now uses a cached MINSAFEINTEGER making it compatible with Internet Explorer (thanks @jronn)
  • The Path class now uses a cached MINSAFEINTEGER making it compatible with Internet Explorer (thanks @jronn)
  • Video.destroy has been renamed to Video.preDestroy, so that it now destroys properly like all other Game Objects. Fix #4821 (thanks @rexrainbow)
  • The Video Game Object will now check to see if the browser supports the HTMLVideoElement before creating one (thanks @jcyuan)
  • The DOM.GetScreenOrientation functions would return out-dated consts (thanks @jcyuan)
  • When calling TileSprite.setTexture or setFrame, if the new frame size didn't match the old one, the new fill pattern would become distorted and the potWidth and potHeight values would be incorrect.
  • Timeline callbacks with extra parameters like onStart would miss the first parameter when the callback was invoked. Fix #4810 (thanks @samme)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@samme (for contributing loads of new Arcade Physics examples) @dranitski @jcyuan @RollinSafary @ilyaryabchinski @jsoref @jcyuan @ghclark2

- JavaScript
Published by photonstorm over 6 years ago

phaser - Phaser 3.20.1

Updates

  • The remove-files-webpack-plugin plugin has been moved to a devDependency (thanks @noseglid)

Bug Fixes

  • UpdateList.shutdown wasn't removing the Scene Update event listener, causing actions to be multiplied on Scene restart (such as animation playback). Fix #4799 (thanks @jronn)
  • Container.mask wouldn't render in WebGL due to a change in the way child masks were handled. Container masking now works again as in 3.19. Fix #4803 (thanks @paulsymphony)
  • DynamicTilemapLayer.setCollision would cause an indexOf error when trying to access the layer data. Fix #4800 (thanks @PavelMishin)
  • SceneManager.run (and consequently ScenePlugin.run) was using an out-dated way of checking if a Scene was paused before trying to resume it, causing a Scene to be started again instead of resumed. It now uses the Systems.isPaused function instead. Fix #3931 (thanks @alexeymolchan)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@xSke

- JavaScript
Published by photonstorm over 6 years ago

phaser - Phaser v3.20.0

Video Game Object

This is a new Game Object is capable of handling playback of a previously loaded video from the Phaser Video Cache, or playing a video based on a given URL. Videos can be either local, or streamed:

```javascript preload () { this.load.video('pixar', 'nemo.mp4'); }

create () { this.add.video(400, 300, 'pixar'); } ```

To all intents and purposes, a video is a standard Game Object, just like a Sprite. And as such, you can do all the usual things to it, such as scaling, rotating, cropping, tinting, making interactive, giving a physics body, etc.

Transparent videos are also possible via the WebM file format. Providing the video file has was encoded with an alpha channel, and providing the browser supports WebM playback (not all of them do), then it willl render in-game with full transparency.

You can also save a video to the Texture Manager, allowing other Game Objects to use it as their texture, including using it as a sampler2D input for a shader.

See the Video Game Object class for more details. Other Video related changes are as follows:

  • Loader.FileTypes.VideoFile is a new Video File Loader File Type, used for preloading videos as streams or blobs.
  • WebGLRenderer.createVideoTexture is a new method that will create a WebGL Texture from the given Video Element.
  • WebGLRenderer.updateVideoTexture is a new method that will update a WebGL Texture from the given Video Element.
  • TextureSource.isVideo is a new boolean property that is set when the Texture Source is backed by an HTML Video Element.
  • Cache.video is a new global cache that store loaded Video content.
  • Device.Video.h264Video has been renamed to Device.Video.h264 to keep it in-line with the Audio Device names.
  • Device.Video.hlsVideo has been renamed to Device.Video.hls to keep it in-line with the Audio Device names.
  • Device.Video.mp4Video has been renamed to Device.Video.mp4 to keep it in-line with the Audio Device names.
  • Device.Video.oggVideo has been renamed to Device.Video.ogg to keep it in-line with the Audio Device names.
  • Device.Video.vp9Video has been renamed to Device.Video.vp9 to keep it in-line with the Audio Device names.
  • Device.Video.webmVideo has been renamed to Device.Video.webm to keep it in-line with the Audio Device names.

Spine Plugin

  • The Spine runtimes have been updated to 3.8. Please note that Spine runtimes are not backwards compatible. Animations exported with Spine 3.7 (or earlier) will need re-exporting with 3.8 in order to work with the new runtimes.
  • Fixed a bug with the binding of the Spine Plugin causing the GameObjectFactory to remain bound to the first instance of the plugin, causing Scene changes to result in blank Spine Game Objects. Fix #4716 (thanks @olilanz)
  • Fixed a bug with the caching of the Spine Texture Atlases, causing shader errors when returning from one Scene to another with a cached Texture Atlas.
  • The WebGL Scene Renderer is now only disposed if the Scene is destroyed, not just shut-down.
  • The Spine Game Object will no longer set the default skin name to be 'default', it will leave the name empty. Fix #4764 (thanks @Jonchun @badlogic)
  • Thanks to a fix inside the Container WebGLRenderer, a bug was crushed which involved multiple Containers in a Scene, with Spine objects, from causing run-time errors. Fix #4710 (thanks @nalgorry)
  • Using Loader.setPath to define the Spine assets locations could error if trying to load multiple files from different folders. It will now retain the path state at the time of invocation, rather than during the load.
  • When loading Spine files that used the same internal image file names, only the first file would successfully load. Now, all files load correctly.

Facebook Instant Games Plugin

  • Calling showAd or showVideoAd will now check to see if the ad has already been displayed, and skip it when iterating the ads array, allowing you to display an ad with the same Placement ID without preloading it again. Fix #4728 (thanks @NokFrt)
  • Calling gameStarted in a game that doesn't load any assets would cause the error {code: "INVALID_OPERATION", message: "Can not perform this operation before game start."}. The plugin will now has a new internal method gameStartedHandler and will redirect the flow accordingly based on asset loading. Fix #4550 (thanks @bchee)
  • The documentation for the chooseContext method has been fixed. Fix #4425 (thanks @krzysztof-grzybek)
  • Leaderboard.getConnectedScores incorrectly specified two parameters, neither of which were used. Fix #4702 (thanks @NokFrt)
  • Leaderboard extends Event Emitter, which was missing in the TypeScript defs. Fix #4703 (thanks @NokFrt)

Arcade Physics Updates

@BenjaminDRichards and the GameFroot team contributed the following updates to Arcade Physics, which fixes 3 issues encountered when the framerate drops below 60 (technically, any time when multiple physics steps run per frame, so if physics FPS is above 60 this will also occur.)

Issue 1: Friction starts to flip out. Objects on moving platforms get pushed ahead of the platform and "catch" on the leading edge. Issue 2: Physics objects start to dip into the floor. In the "Before" demo, the camera is locked to the player, so this appears as the entire world starting to shake up and down. Issue 3: When objects dip into the floor, their "rest velocity" is non-zero. This can affect debug and other logic.

  • Body.prevFrame is a new vector allowing a Body to distinguish between frame-length changes and step-length changes. Several steps may run for every frame, particularly when fps is low.
  • Body._reset flag was removed and replaced it with a check of Body.moves. The flag only turned on when moves was true, and never turned off.
  • Added a reset of prev in Arcade.Body#step. This fixes the friction issue.
  • Stopped the Body.postUpdate method from setting _dx, _dy, and prev. They remain in the state they were at the end of the last physics step. This will affect the delta methods, which are documented to provide step-based data (not frame-based data); they now do so. However, because several steps may run per frame, you can't interrogate every step unless you're running functions based on physics events like collisions. You'll just see the latest step. This should partially balance out the extra load of resetting prev.
  • Added a zero-out of stepsLastFrame in Arcade.World#postUpdate, which would otherwise never zero out and keep running at least one pass per frame. This should improve performance when frames can be skipped.
  • Removed blocked checks from TileCheckX and TileCheckY. Originally, this prevented multiple checks when an object had come to rest on a floor. However, when multiple steps run per frame, the object will accelerate again, the floor won't stop it on steps 2+, and it will end the frame a short distance into the floor. Removing the blocked checks will fix the floor dip issue and the rest velocity issue. Although this opens up multiple checks, this is probably very rare: how many times does an object hit two different floors in a single frame?

In combination these updates fix issues #4732 and #4672. My thanks to @BenjaminDRichards and @falifm.

New Features

  • GameConfig.antialiasGL is a new boolean that allows you to set the antialias property of the WebGL context during creation, without impacting any subsequent textures or the canvas CSS.
  • InteractiveObject.alwaysEnabled is a new boolean that allows an interactive Game Object to always receive input events, even if it's invisible or won't render.
  • Bob.setTint is a new method that allows you to set the tint of a Bob object within a Blitter. This is then used by the Blitter WebGL Renderer (thanks @rexrainbow)
  • The UpdateList now emits two new events: 'add' and 'remove' when children are added and removed from it. Fix #3487 (thanks @hexus)
  • The Tilemap.setCollision method has a new optional boolean parameter updateLayer. If set to true, it will update all of the collision settings of all tiles on the layer. If false it will skip doing this, which can be a huge performance boost in situations where the layer tiles haven't been modified and you're just changing collision flags. This is especially suitable for maps using procedural generated tilemaps, infinite tilemaps, multiplayer tilemaps, particularly large tilemaps (especially those dyanmic in nature) or who otherwise intend to index collisions before the tiles are loaded. This update also added the new parameter to the SetCollision, SetCollisionBetween and DynamicTilemapLayer.setCollision methods (thanks @tarsupin)
  • ArcadePhysics.Body.setBoundsRectangle is a new method that allows you to set a custom bounds rectangle for any Body to use, rather than the World bounds, which is the default (thanks @francois-n-dream)
  • ArcadePhysics.Body.customBoundsRectangle is a new property used for custom bounds collision (thanks @francois-n-dream)
  • The Arcade Physics Group has a new config object property customBoundsRectangle which, if set, will set the custom world bounds for all Bodies that Group creates (thanks @francois-n-dream)
  • WebGLRenderer.createTexture2D has a new optional parameter flipY which sets the UNPACK_FLIP_Y_WEBGL flag of the uploaded texture.
  • WebGLRenderer.canvasToTexture has a new optional parameter flipY which sets the UNPACK_FLIP_Y_WEBGL flag of the uploaded texture.
  • WebGLRenderer.createCanvasTexture is a new method that will create a WebGL Texture based on the given Canvas Element.
  • WebGLRenderer.updateCanvasTexture is a new method that will update an existing WebGL Texture based on the given Canvas Element.
  • WebGLRenderer.createVideoTexture is a new method that will create a WebGL Texture based on the given Video Element.
  • WebGLRenderer.updateVideoTexture is a new method that will update an existing WebGL Texture based on the given Video Element.
  • TextureSource.flipY is a new boolean that controls if the UNPACK_FLIP_Y_WEBGL flag is set when a WebGL Texture is uploaded.
  • TextureSource.setFlipY is a new method that toggles the TextureSource.flipY property.

Updates

  • When calling Shader.setRenderToTexture() it will now draw the shader just once, immediately to the texture, to avoid the texture being blank for a single frame (thanks Kyle)
  • The private Shader._savedKey property has been removed as it wasn't used anywhere internally.
  • A hasOwnProperty check has been applied to the SceneManager.createSceneFromObject method when parsing additional properties in the extend object (thanks @halilcakar)
  • The Blitter.dirty flag is no longer set if the render state of a Bob is changed to make it invisible (thanks @rexrainbow)
  • WebGLPipeline.addAttribute will now automatically update the vertextComponentCount for you, without you having to do it manually any more (thanks @yhwh)
  • MultiFile has three new internal properties: baseURL, path and prefix which allow them to retain the state of the loader at the time of creation, to be passed on to all child-files. Fix #4679.
  • LoaderPlugin and MultiFile have a new private property multiKeyIndex which multi-files use and increment when batching sub-file loads.
  • TileSprites will now throw a console warning if you try to use a RenderTexture or GLTexture as their frame source. Fix #4719 (thanks @pavel-shirobok)
  • TextureSource.isGLTexture now checks if the browser supports WebGLTexture before checking to see if source is an instance of one. This should fix issues with Phaser in HEADLESS mode running under node / jsdom, or where WebGLTexture isn't present. Fix #4711 (thanks @tsphillips)
  • GameObject.ToJSON will no longer output the scaleMode in the json because it's not a valid Game Object property.
  • TextureSource.setFilter will now set the scaleMode to the given filter.
  • CanvasInterpolation has updated the order of the CSS properties so that crisp-edges comes after the browser prefix versions.
  • The CanvasRenderer.scaleMode property has been removed as it was never set or used internally.
  • The CanvasRenderer.currentScaleMode property has been removed as it was never set or used internally.
  • The BuildGameObject function will no longer set scaleMode because it's not a valid Game Object property.
  • CanvasRenderer.antialias is a new property, populated by the game config property of the same name (or via the pixelArt property) that will tell the canvas renderer what to set image interpolation to during rendering of Sprites.
  • SetTransform will now set the imageSmoothingEnabled context value based on the renderer and texture source scale mode.
  • The Blitter Canvas Renderer will now respect the game config anti-alias / pixel art settings and render accordingly.
  • The Particle Emitter Canvas Renderer will now respect the game config anti-alias / pixel art settings and render accordingly.
  • The Static Tilemap Canvas Renderer will now respect the game config anti-alias / pixel art settings and render accordingly.
  • The Dynamic Tilemap Canvas Renderer will now respect the game config anti-alias / pixel art settings and render accordingly.
  • All Game Objects that use the Canvas Set Transform function (which is most of them) will aos now respect the game config anti-alias / pixel art settings and render accordingly. This means you can now have properly scaled Bitmap Text, Text, Sprites, Render Textures, etc when pixel art is enabled in your game. Fix #4701 (thanks @agar3s)
  • Containers are now able to set the alpha quadrant values (topLeft, topRight, bottomLeft and bottomRight) and have these passed onto children which are capable of supporting them, such as Sprites. Fix #4714 (thanks @MrcSnm)
  • The ProcessQueue struct now extends Event Emitter and will emit PROCESS_QUEUE_ADD_EVENT when a new item is added to it.
  • The ProcessQueue struct now extends Event Emitter and will emit PROCESS_QUEUE_REMOVE_EVENT when an item is removed from it.
  • ProcessQueue.removeAll is a new method that will remove all active entries from the queue.
  • ProcessQueue.length is a new property that returns the size of the active list.
  • UpdateList now extends the ProcessQueue struct and uses all of its methods for list management, instead of doing it directly. This means private properties such as UpdateList._list no longer exist. It also fixes an issue re: memory management where list items would remain until the end of a Scene. Fix #4721 (thanks @darkgod6)
  • BaseSoundManager.forEachActiveSound will now only invoke the callback if the sound actually exists and isn't pending removal. Fix #3383 (thanks @DouglasLapsley)
  • MouseManager.target can now be defined as either a string or by passing an HTMLElement directly. Fix #4353 (thanks @BigZaphod)
  • The BasePlugin.boot method has been removed and moved to ScenePlugin.boot as it's a Scene-level method only (thanks @samme)
  • The BasePlugin.scene and BasePlugin.systems properties have been removed and are defined in ScenePlugin, as they are Scene-level properties only (thanks @samme)
  • The Tween.getValue method has been updated so you can specify the index of the Tween Data to get the value of. Previously, it only returned the first TweenData from the data array, ignoring any subsequent properties or targets. Fix #4717 (thanks @chepe263)
  • WebGLRenderer.createTexture2D has a new optional parameter forceSize, which will force the gl texture creation to use the dimensions passed to the method, instead of extracting them from the pixels object, if provided.
  • The GameObject.setTexture method can now accept either a string, in which case it looks for the texture in the Texture Manager, or a Texture instance, in which case that instance is set as the Game Object's texture.
  • TextureManager.get can now accept either a string-based key, or a Texture instance, as its parameter.
  • SceneManager.stop and the matching ScenePlugin.stop now have an optional data parameter, which is passed to the Scene shutdown method. Fix #4510 (thanks @Olliebrown @GetsukenStudios)
  • Cameras.BaseCamera is now exposed in the namespace, allowing you to access them directly (thanks @rexrainbow)
  • Shaders have a new optional constructor parameter textureData which allows you to specify additional texture data, especially for NPOT textures (thanks @cristlee)
  • TouchManager.disableContextMenu is a new method that will try to disable the context menu on touch devices, if the Game Config disableContextMenu is set. Previously, it only tried to do it for the Mouse Manager, but now does it for touch as well. Fix #4778 (thanks @simplewei)

Bug Fixes

  • SpineCanvasPlugin.shutdown would try to dispose of the sceneRenderer, but the property isn't set for Canvas.
  • ArcadePhysics.Body.checkWorldBounds would incorrectly report as being on the World bounds if the blocked.none flag had been toggled elsewhere in the Body. It now only sets if it toggles a new internal flag (thanks Pablo)
  • RenderTexture.resize wouldn't update the CanvasTexture width and height, causing the cal to draw or drawFrame to potentially distort the texture (thanks @yhwh)
  • InputPlugin.processDragMove has been updated so that the resulting dragX and dragY values, sent to the event handler, now compensate for the scale of the Game Objects parent container, if inside of one. This means dragging a child of a scale Container will now still drag at 'full' speed.
  • The RenderTextures displayOrigin values are now automatically updated if you call setSize on the Render Texture. Fix #4757 (thanks @rexrainbow)
  • onTouchStart, onTouchEnd and onTouchMove will now check for event.cancelable before calling preventDefault on the touch event, fixing issues with "Ignored attempt to cancel a touchstart event with cancelable=false, for example because scrolling is in progress and cannot be interrupted." errors in some situations. Fix #4706 (thanks @MatthewAlner)
  • MatterPhysics.shutdown could try to access properties that may have been previously removed during the Game.destroy process, causing a console error. It now checks properties before removing events from them (thanks @nagyv)
  • ArcadePhysics.Body.hitTest would use CircleContains to do a hit test, which assumex x/y was the Circle center, but for a Body it's the top-left, causing the hit test to be off. Fix #4748 (thanks @funnisimo)
  • ArcadePhysics.World.separateCircle has had the velocity scaling moved to after the angle is calculated, fixing a weird collision issue when Body.bounce=0. Also, if both bodies are movable, they now only offset by half the offset and use the center of the body for angle calculation, allowing for any offsets to be included. Fix #4751 (thanks @funnisimo @hizzd)
  • Tween.updateTo would break out of the TweenData iteration as soon as it adjusted the first matching key, causing tweens acting on multiple targets to only update the first target. It now updates them all. Fix #4763 (thanks @RBrNx)
  • The Container WebGLRenderer will now handle child mask batching properly, based on the renderers current mask.
  • The Container WebGLRenderer will now handle child new type switching, allowing you to carry on with a batch of same-type Game Objects even if they're nested within Containers. Fix #4710 (thanks @nalgorry)
  • MultiAtlasFiles that loaded their own external images would obtain incorrect path and URL values if the path had been changed by another file in the queue. They now retain the loader state and apply it to all child files during load.
  • If more than one MultiAtlasFile used the same internal file name for its images, subsequent multi-atlases would fail to load. Fix #4330 (thanks @giviz)
  • MultiAtlasFiles would incorrectly add the atlas JSON into the JSON cache, causing you to not be able to destroy and reload the texture using the same atlas key as before. Fix #4720 (thanks @giviz)
  • RenderTexture.fill wasn't setting the camera up before drawing the fill rect, causing it to appear in the wrong place and the wrong size. Fix #4390 (thanks @Jerenaux)
  • DynamicBitmapText.setOrigin wouldn't change the origin when using the Canvas Renderer, only in WebGL. It now sets the origin regardless of renderer. Fix #4108 (thanks @garethwhittaker)
  • DynamicBitmapText wouldn't respect the multi-line alignment values when using the Canvas Renderer. It now uses them in the line calculations.
  • DynamicBitmapText and BitmapText wouldn't render at the correct position when using scaled BitmapText and an origin. Fix #4054 (thanks @Aveyder)
  • Incorrect lighting on batched Sprites. The lighting was not correct when batching several sprites with different rotations. Each sprite now uses its own uInverseRotationMatrix to compute the lighting correctly (thanks @gogoprog)
  • Matter.js Body wasn't setting the part angles correctly in Body.update (thanks @Frozzy6)
  • ScaleManager.startFullscreen now checks to see if the call returns a Promise, rather than checking if the browser supports them, before waiting for promise resolution. This fixes a runtime console warning in Microsoft Edge. Fix #4795 (thanks @maksdk)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@krzysztof-grzybek @NokFrt @r-onodera @colorcube @neon-dev @SavedByZero @arnekeller

Thanks

Thank you to the following people for contributing ideas for new features to be added to Phaser 3. Because we've now started Phaser 4 development, I am closing off old feature requests that I personally will not work on for Phaser 3 itself. They may be considered for v4 and, of course, if someone from the community wishes to submit a PR to add them, I will be only too happy to look at that. So, if you want to get involved, filter the GitHub issues by the Feature Request tag and dig in. In the meantime, thank you to the following people for suggesting features, even if they didn't make it this time around:

@njt1982 @TheTrope @allanbreyes @alexandernst @Secretmapper @murteira @oktayacikalin @TadejZupancic @SBCGames @hadikcz @jcyuan @pinkkis @Aedalus @jestarray @BigZaphod @Secretmapper @francois-n-dream @G-Rath

- JavaScript
Published by photonstorm over 6 years ago

phaser - Phaser v3.19.0

Version 3.19.0 - Naofumi - 8th August 2019

Tween Updates

  • All Tween classes and functions have 100% complete JSDocs :)
  • StaggerBuilder is a new function that allows you to define a staggered tween property. For example, as part of a tween config: delay: this.tweens.stagger(500) would stagger the delay by 500ms for every target of the tween. You can also provide a range: delay: this.tweens.stagger([ 500, 1000 ]) which is spread across all targets. Finally, you can provide a Stagger Config object as the second argument. This allows you to define a stagger grid, direction, starting value and more. Please see the API Docs and new Examples for further details.
  • Tween now extends the Event Emitter class, allowing it to emit its own events and be listened to.
  • Tween.ACTIVE_EVENT is a new event that is dispatched when a tween becomes active. Listen to it with tween.on('active').
  • Tween.COMPLETE_EVENT is a new event that is dispatched when a tween completes or is stopped. Listen to it with tween.on('complete').
  • Tween.LOOP_EVENT is a new event that is dispatched when a tween loops, after any loop delay expires. Listen to it with tween.on('loop').
  • Tween.REPEAT_EVENT is a new event that is dispatched when a tween property repeats, after any repeat delay expires. Listen to it with tween.on('repeat').
  • Tween.START_EVENT is a new event that is dispatched when a tween starts. Listen to it with tween.on('start').
  • Tween.UPDATE_EVENT is a new event that is dispatched when a tween property updates. Listen to it with tween.on('update').
  • Tween.YOYO_EVENT is a new event that is dispatched when a tween property yoyos, after any hold delay expires. Listen to it with tween.on('yoyo').
  • Tween.onActive is a new callback that is invoked the moment the Tween Manager brings the tween to life, even though it may not have yet started actively tweening anything due to delay settings.
  • Tween.onStart is now only invoked when the Tween actually starts tweening a value. Previously, it was invoked as soon as the Tween Manager activated the Tween. This has been recoded and this action is now handled by the onActive callback. Fix #3330 (thanks @wtravO)
  • Tween.seek has been rewritten so you can now seek to any point in the Tween, regardless of repeats, loops, delays and hold settings. Seeking will not invoke any callbacks or events during the seek. Fix #4409 (thanks @cristib84)
  • You can now set from and to values for a property, i.e. alpha: { from: 0, to: 1 } which would set the alpha of the target to 0 and then tween it to 1 after any delays have expired. Fix #4493 (thanks @BigZaphod)
  • You can now set start and to values for a property, i.e. alpha: { start: 0, to: 1 } which would set the alpha of the target to 0 immediately, as soon as the Tween becomes active, and then tween it to 1 over the duration of the tween.
  • You can now set start, from and to values for a property, i.e. alpha: { start: 0, from: 0.5, to: 1 } which would set the alpha of the target to 0 immediately, as soon as the Tween becomes active, then after any delays it would set the alpha to 0.5 and then tween it to 1 over the duration of the Tween.
  • Tween.hasStarted is a new property that holds a flag signifying if the Tween has started or not. A Tween that has started is one that is actively tweening a property and not just in a delayed state.
  • Tween.startDelay is a new property that is set during the Tween init to hold the shortest possible time before the Tween will start tweening a value. It is decreased each update until it hits zero, after which the onStart callback is invoked.
  • Tween.init and Tween.play have been rewritten so they are not run multiple times when a Tween is paused before playback, or is part of a Timeline. This didn't cause any problems previously, but it was a redundant duplication of calls.
  • Tween.onLoop will now be invoked after the loopDelay has expired, if any was set.
  • Tween.onRepeat will now be invoked after the repeatDelay has expired, if any was set.
  • easeParams would be ignored for tweens that didn't use a string for the ease function name. Fix #3826 (thanks @SBCGames)
  • You can now specify easeParams for any custom easing function you wish to use. Fix #3826 (thanks @SBCGames)
  • All changes to Tween.state are now set before any events or callbacks, allowing you to modify the state of the Tween in those handlers (thanks @Cudabear)
  • Tween.dispatchTweenEvent is a new internal method that handles dispatching the new Tween Events and callbacks. This consolidates a lot of duplicate code into a single method.
  • Tween.dispatchTweenDataEvent is a new internal method that handles dispatching the new TweenData Events and callbacks. This consolidates a lot of duplicate code into a single method.
  • Tween.isSeeking is a new internal boolean flag that is used to keep track of the seek progress of a Tween.
  • Timeline.onLoop will now be invoked after the loopDelay has expired, if any was set.
  • Timeline.onComplete will now be invoked after the completeDelay has expired, if any was set.
  • All changes to Timeline.state are now set before any events or callbacks, allowing you to modify the state of the Timeline in those handlers.
  • The TIMELINE_LOOP_EVENT has had the loopCounter argument removed from it. It didn't actually send the number of times the Timeline had looped (it actually sent the total remaining).
  • When a TweenData completes it will now set the current property to be exactly either start or end depending on playback direction.
  • When a TweenData completes it will set the exact start or end value into the target property.
  • TweenData has a new function signature, with the new index and getActivearguments added to it. TweenBuilder has been updated to set these, but if you create any TweenData objects directly, use the new signature.
  • TweenData.getActiveValue is a new property that, if not null, returns a value to immediately sets the property value to on activation.
  • GetEaseFunction, and by extension anything that uses it, such as setting the ease for a Tween, will now accept a variety of input strings as valid. You can now use lower-case, such as back, and omit the 'ease' part of the direction, such as back.in or back.inout.
  • The signature of getStart and getEnd custom property functions has changed to (target, key, value, targetIndex, totalTargets, tween), previously it was just (target, key, value). Custom functions don't need to change as the new arguments are in addition to those sent previously.
  • The signature of the LoadValue generator functions (such as delay and repeat) has changed to (target, key, value, targetIndex, totalTargets, tween) to match those of the custom property functions. If you used a custom generator function for your Tween configs you'll need to modify the signature to the new one.
  • Tweens created via TweenManager.create wouldn't start when Tween.play was called without first making them active manually. They now start automatically. Fix #4632 (thanks @mikewesthad)

Spine Updates

The Spine Plugin is now 100% complete. It has been updated to use the Spine 3.7 Runtimes. Improvements have been made across the entire plugin, including proper batched rendering support in WebGL, cleaner skin and slot functions and lots and lots of updates. It's fully documented and there are lots of examples to be found. The following legacy bugs have also been fixed:

  • Adding Spine to physics causes position to become NaN. Fix #4501 (thanks @hizzd)
  • Destroying a Phaser Game instance and then re-creating it would cause an error trying to re-create Spine Game Objects ("Cannot read property get of null"). Fix #4532 (thanks @Alex-Badea)
  • Rendering a Spine object when a Camera has renderToTexture enabled on it would cause the object to be vertically flipped. It now renders correctly in both cases. Fix #4647 (thanks @probt)

New Features

  • Shader.setRenderToTexture is a new method that will redirect the Shader to render to its own framebuffer / WebGLTexture instead of to the display list. This allows you to use the output of the shader as an input for another shader, by mapping a sampler2D uniform to it. It also allows you to save the Shader to the Texture Manager, allowing you to use it as a texture for any other texture based Game Object such as a Sprite.
  • Shader.setSampler2DBuffer is a new method that allows you to pass a WebGLTexture directly into a Shader as a sampler2D uniform, such as when linking shaders together as buffers for each other.
  • Shader.renderToTexture is a new property flag that is set if you set the Shader to render to a texture.
  • Shader.framebuffer is a new property that contains a WebGLFramebuffer reference which is set if you set the Shader to render to a texture.
  • Shader.glTexture is a new property that contains a WebGLTexture reference which is set if you set the Shader to render to a texture.
  • Shader.texture is a new property that contains a Phaser Texture reference which is set if you set the Shader to save to the Texture Manager.
  • TextureManager.addGLTexture is a new method that allows you to add a WebGLTexture directly into the Texture Manager, saved under the given key.
  • TextureSource.isGLTexture is a new boolean property that reflects if the data backing the underlying Texture Source is a WebGLTexture or not.
  • TextureTintPipeline.batchSprite will now flip the UV if the TextureSource comes from a GLTexture.
  • Math.ToXY is a new mini function that will take a given index and return a Vector2 containing the x and y coordinates of that index within a grid.
  • RenderTexture.glTexture is a new property that holds a reference to the WebGL Texture being used by the Render Texture. Useful for passing to a shader as a sampler2D.
  • GroupCreateConfig.quantity - when creating a Group using a config object you can now use the optional property quantity to set the number of objects to be created. Use this for quickly creating groups of single frame objects that don't need the advanced capabilities of frameQuantity and repeat.
  • Pointer.locked is a new read-only property that indicates if the pointer has been Pointer Locked, or not, via the Pointer Lock API.
  • WebGLRenderer.snapshotFramebuffer, and the corresponding utility function WebGLSnapshot, allows you to take a snapshot of a given WebGL framebuffer, such as the one used by a Render Texture or Shader, and either get a single pixel from it as a Color value, or get an area of it as an Image object, which can then optionally be saved to the Texture Manager for use by Game Object textures.
  • CanvasRenderer.snapshotCanvas allows you to take a snapshot of a given Canvas object, such as the one used by a Render Texture, and either get a single pixel from it as a Color value, or get an area of it as an Image object, which can then optionally be saved to the Texture Manager for use by Game Object textures.
  • RenderTexture.snapshot is a new method that will take a snapshot of the whole current state of the Render Texture and return it as an Image object, which could then be saved to the Texture Manager if needed.
  • RenderTexture.snapshotArea is a new method that will take a snapshot of an area of a Render Texture and return it as an Image object, which could then be saved to the Texture Manager if needed.
  • RenderTexture.snapshotPixel is a new method that will take extract a single pixel color value from a Render Texture and return it as a Color object.
  • The SnapshotState object has three new properties: isFramebuffer boolean and bufferWidth and bufferHeight integers.
  • Game.CONTEXT_LOST_EVENT is a new event that is dispatched by the Game instance when the WebGL Renderer webgl context is lost. Use this instead of the old 'lostContextCallbacks' for cleaner context handling.
  • Game.CONTEXT_RESTORED_EVENT is a new event that is dispatched by the Game instance when the WebGL Renderer webgl context is restored. Use this instead of the old 'restoredContextCallbacks' for cleaner context handling.
  • WebGLRenderer.currentType contains the type of the Game Object currently being rendered.
  • WebGLRenderer.newType is a boolean that indicates if the current Game Object has a new type, i.e. different to the previous one in the display list.
  • WebGLRenderer.nextTypeMatch is a boolean that indicates if the next Game Object in the display list has the same type as the one being currently rendered. This allows you to build batching into separated Game Objects.
  • PluginManager.removeGameObject is a new method that allows you to de-register custom Game Object types from the global Game Object Factory and/or Creator. Useful for when custom plugins are destroyed and need to clean-up after themselves.
  • GEOM_CONST is a new constants object that contains the different types of Geometry Objects, such as RECTANGLE and CIRCLE.
  • Circle.type is a new property containing the shapes geometry type, which can be used for quick type comparisons.
  • Ellipse.type is a new property containing the shapes geometry type, which can be used for quick type comparisons.
  • Line.type is a new property containing the shapes geometry type, which can be used for quick type comparisons.
  • Point.type is a new property containing the shapes geometry type, which can be used for quick type comparisons.
  • Polygon.type is a new property containing the shapes geometry type, which can be used for quick type comparisons.
  • Rectangle.type is a new property containing the shapes geometry type, which can be used for quick type comparisons.
  • Triangle.type is a new property containing the shapes geometry type, which can be used for quick type comparisons.
  • InputPlugin.enableDebug is a new method that will create a debug shape for the given Game Objects hit area. This allows you to quickly check the size and placement of an input hit area. You can customzie the shape outline color. The debug shape will automatically track the Game Object to which it is bound.
  • InputPlugion.removeDebug will remove a Debug Input Shape from the given Game Object and destroy it.
  • Pointer.updateWorldPoint is a new method that takes a Camera and then updates the Pointers worldX and worldY values based on the cameras transform (thanks @Nick-lab)
  • ScaleManager._resetZoom is a new internal flag that is set when the game zoom factor changes.
  • Texture.remove is a new method that allows you to remove a Frame from a Texture based on its name. Fix #4460 (thanks @BigZaphod)

Updates

  • When calling setHitArea and not providing a shape (i.e. a texture based hit area), it will now set customHitArea to false by default (thanks @rexrainbow)
  • The Shader will no longer set uniforms if the values are null, saving on GL ops.
  • The Animation Manager will now emit a console warning if you try and play an animation on a Sprite that doesn't exist.
  • The Animation component will no longer start an animation on a Sprite if the animation doesn't exist. Previously it would throw an error saying "Unable to read the property getFirstTick of null".
  • InputManager.onPointerLockChange is a new method that handles pointer lock change events and dispatches the lock event.
  • CanvasTexture has been added to the Textures namespace so it can be created without needing to import it. The correct way to create a CanvasTexture is via the Texture Manager, but you can now do it directly if required. Fix #4651 (thanks @Jugacu)
  • The SmoothedKeyControl minimum zoom a Camera can go to is now 0.001. Previously it was 0.1. This is to make it match the minimum zoom a Base Camera can go to. Fix #4649 (thanks @giviz)
  • WebGLRenderer.lostContextCallbacks and the onContextLost method have been removed. Please use the new CONTEXT_LOST event instead.
  • WebGLRenderer.restoredContextCallbacks and the onContextRestored method have been removed. Please use the new CONTEXT_RESTORED event instead.
  • TextureManager.getBase64 will now emit a console warning if you try to get a base64 from a non-image based texture, such as a WebGL Texture.
  • The WebAudioSoundManager will now remove the document touch handlers even if the Promise fails, preventing it from throwing a rejection handler error.
  • GameObjectFactory.remove is a new static function that will remove a custom Game Object factory type.
  • GameObjectCreator.remove is a new static function that will remove a custom Game Object creator type.
  • CanvasTexture.getPixels now defaults to 0x0 by width x height as the default area, allowing you to call the method with no arguments to get all the pixels for the canvas.
  • CreateDOMContainer will now use div.style.cssText to set the inline styles of the container, so it now works on IE11. Fix #4674 (thanks @DanLiamco)
  • TransformMatrix.rotation now returns the properly normalized rotation value.
  • PhysicsEditorParser has now been exposed under the Phaser.Physics.Matter namespace, so you can call methods on it directly.
  • Calling CanvasTexture.update will now automatically call refresh if running under WebGL. This happens for both draw and drawFrame, meaning you no longer need to remember to call refresh after drawing to a Canvas Texture in WebGL, keeping it consistent with the Canvas renderer.
  • Frame.destroy will now null the Frames reference to its parent texture, glTexture and clear the data and customData objects.
  • The Container renderer functions will now read the childs alpha property, instead of _alpha, allowing it to work with more variety of custom children.

Bug Fixes

  • The Scale Manager would throw the error 'TypeError: this.removeFullscreenTarget is not a function' when entering full-screen mode. It would still enter fullscreen, but the error would appear in the console. Fix #4605 (thanks @darklightcode)
  • Tilemap.renderDebug was calling out-dated Graphics API methods, which would cause the debug to fail (thanks @Fabadiculous)
  • The Matter.Factory.constraint, joint and worldConstraint methods wouldn't allow a zero length constraint to be created due to a falsey check of the length argument. You can now set length to be any value, including zero, or leave it undefined to have it automatically calculated (thanks @olilanz)
  • Pointer.getDuration would return a negative / static value on desktop, or NaN on mobile, because the base time wasn't being pulled in from the Input Manager properly. Fix #4612 (thanks @BobtheUltimateProgrammer)
  • Pointer.downTime, Pointer.upTime and Pointer.moveTime would be set to NaN on mobile browsers where Touch.timeStamp didn't exist. Fix #4612 (thanks @BobtheUltimateProgrammer)
  • WebGLRenderer.setScissor will default the drawingBufferHeight if no argument is provided, stopping NaN scissor heights.
  • If you called Scene.destroy within a Game Object pointerdown or pointerup handler, it would cause the error "Cannot read property 'game' of null" if the event wasn't cancelled in your handler. It now checks if the manager is still there before accessing its property. Fix #4436 (thanks @jcyuan)
  • The Arc / Circle Game Object wasn't rendering centered correctly in WebGL due to an issue in a previous size related commit, it would be half a radius off. Fix #4620 (thanks @CipSoft-Components @rexrainbow)
  • Destroying a Scene in HEADLESS mode would throw an error as it tried to access the gl renderer in the Camera class. Fix #4467 (thanks @AndreaBoeAbrahamsen @samme)
  • Tilemap.createFromObjects would ignore the scene argument passed in to the method. It's now used (thanks @samme)
  • Fixed a bug in the WebGL and Canvas Renderers where a Sprite with a flipX or flipY value set would render the offset frames slightly out of place, causing the animation to appear jittery. Also, the sprite would be out of place by its origin. Fix #4636 #3813 (thanks @jronn @B3L7)
  • Animations with custom pivots, like those created in Texture Packer with the pivot option enabled, would be mis-aligned if flipped. They now render in the correct position, regardless of scale or flip on either axis. Fix #4155 (thanks @Zax37)
  • Removing a frame from a 2 frame animation would cause an error when a Sprite using that animation next tried to render. Fix #4621 (thanks @orlicgms)
  • Calling Animation.setRepeat() wouldn't reset the repeatCounter properly, causing Sprite bound animation instances to fail to change their repeat rate. Fix #4553 (thanks @SavedByZero)
  • The UpdateList.remove method wouldn't flag the Game Object for removal properly if it was active. It now checks that the Game Object is in the current update list and hasn't already been inserted into the 'pending removal' list before flagging it. Fix #4544 (thanks @jcyuan)
  • DynamicTilemapLayer.destroy will now no longer run its destroy sequence again if it has already been run once. Fix #4634 (thanks @CipSoft-Components)
  • StaticTilemapLayer.destroy will now no longer run its destroy sequence again if it has already been run once.
  • Shader.uniforms now uses Extend instead of Clone to perform a deep object copy, instead of a shallow one, avoiding multiple instances of the same shader sharing uniforms. Fix #4641 (thanks @davidmball)
  • Calling input.mouse.requestPointerLock() will no longer throw an error about being unable to push to the Input Manager events queue.
  • The POINTERLOCK_CHANGE event is now dispatched by the Input Manager again.
  • The Pointer.movementX and Pointer.movementY properties are now taken directly from the DOM pointer event values, if the pointer is locked, and no longer incremental. Fix #4611 (thanks @davidmball)
  • The Pointer.velocity and Pointer.midPoint values are now updated every frame. Based on the motionFactor setting they are smoothed towards zero, for velocity, and the pointer position for the mid point. This now happens regardless if the Pointer moves or not, which is how it was originally intended to behave.
  • The DESTROY event hook wasn't removed from Group children when destroying the Group and destroyChildren was set to false. Now, the hook is removed regardless (thanks @rexrainbow)
  • The WebGL Lost and Restored Context callbacks were never removed, which could cause them to hold onto stale references. Fix #3610 (thanks @Twilrom)
  • Origin.updateDisplayOrigin no longer applies a Math.floor to the display origins, allowing you to have a 0.x origin for a Game Object that only has a width or height of 1. This fixes issues with things like 1x1 rectangles displaying incorrectly during rendering. Fix #4126 (thanks @rexrainbow)
  • InputManager.resetCursor will now check if the canvas element still exists before resetting the cursor on it. Fix #4662 (thanks @fromnowhereuser)
  • It was not possible to set the zoom value of the Scale Manager back to 1 again, having changed it to a different value. Fix #4633 (thanks @lgibson02 @BinaryMoon)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@vacarsu @KennethGomez @samme @ldd @Jazcash @jcyuan @LearningCode2023 @PhaserEditor2D

- JavaScript
Published by photonstorm almost 7 years ago

phaser - Phaser v3.18.1

Bug Fixes

  • InputManager.preRender didn't get the time property correctly, causing input plugin methods that relied on it to fail.
  • KeyboardPlugin.time wasn't being set to the correct value, causing checkDown to fail constantly.

- JavaScript
Published by photonstorm almost 7 years ago

phaser - Phaser v3.18.0

Input System Changes

Mouse Wheel Support

3.18 now includes native support for reading mouse wheel events.

  • POINTER_WHEEL is a new event dispatched by the Input Plugin allowing you to listen for global wheel events.
  • GAMEOBJECT_WHEEL is a new event dispatched by the Input Plugin allowing you to listen for global wheel events over all interactive Game Objects in a Scene.
  • GAMEOBJECT_POINTER_WHEEL is a new event dispatched by a Game Object allowing you to listen for wheel events specifically on that Game Object.
  • Pointer.deltaX is a new property that holds the horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device.
  • Pointer.deltaY is a new property that holds the vertical scroll amount that occurred due to the user moving a mouse wheel or similar input device.
  • Pointer.deltaZ is a new property that holds the z-axis scroll amount that occurred due to the user moving a mouse wheel or similar input device.
  • Pointer.wheel is a new internal method that handles the wheel event.
  • InputManager.onMouseWheel is a new internal method that handles processing the wheel event.
  • InputManager.processWheelEvent is a new internal method that handles processing the wheel event sent by the Input Manager.

Button Released Support

  • Pointer.button is a new property that indicates which button was pressed, or released, on the pointer during the most recent event. It is only set during up and down events and is always 0 for Touch inputs.
  • Pointer.leftButtonReleased is a new method that returns true if it was the left mouse button that was just released. This can be checked in a pointerup event handler to find out which button was released.
  • Pointer.rightButtonReleased is a new method that returns true if it was the right mouse button that was just released. This can be checked in a pointerup event handler to find out which button was released (thanks @BobtheUltimateProgrammer)
  • Pointer.middleButtonReleased is a new method that returns true if it was the middle mouse button that was just released. This can be checked in a pointerup event handler to find out which button was released.
  • Pointer.backButtonReleased is a new method that returns true if it was the back mouse button that was just released. This can be checked in a pointerup event handler to find out which button was released.
  • Pointer.forwardButtonReleased is a new method that returns true if it was the forward mouse button that was just released. This can be checked in a pointerup event handler to find out which button was released.

Input System Bug Fixes

  • Calling setPollAlways() would cause the 'pointerdown' event to fire multiple times. Fix #4541 (thanks @Neyromantik)
  • The pointer events were intermittently not registered, causing pointerup to often fail. Fix #4538 (thanks @paulsymphony)
  • Due to a regression in 3.16 the drag events were not performing as fast as before, causing drags to feel lagged. Fix #4500 (thanks @aliblong)
  • The Touch Manager will now listen for Touch Cancel events on the Window object (if inputWindowEvents is enabled in the game config, which it is by default). This allows it to prevent touch cancel actions, like opening the dock on iOS, from causing genuinely active pointers to enter an active locked state.
  • Over and Out events now work for any number of pointers in multi-touch environments, not just the first touch pointer registered. They also now fire correctly on touch start and touch end / cancel events.
  • If you enable a Game Object for drag and place it inside a rotated Container (of any depth), the dragX and dragY values sent to the drag callback didn't factor the rotation in, so you had to do it manually. This is now done automatically, so the values account for parent rotation before being sent to the event handler. Fix #4437 (thanks @aliblong)

Input System API Changes

The old 'input queue' legacy system, which was deprecated in 3.16, has been removed entirely in order to tidy-up the API and keep input events consistent. This means the following changes:

  • Removed the inputQueue Game config property.
  • Removed the useQueue, queue and _updatedThisFrame properties from the Input Manager.
  • Removed the legacyUpdate and update methods from the Input Manager.
  • Removed the ignoreEvents property as this should now be handled on a per-event basis.
  • The Input Manager no longer listens for the GameEvents.POST_STEP event.
  • The following Input Manager methods are no longer required so have been removed: startPointer, updatePointer, stopPointer and cancelPointer.

As a result, all of the following Input Manager methods have been renamed:

  • queueTouchStart is now called onTouchStart and invoked by the Touch Manager.
  • queueTouchMove is now called onTouchMove and invoked by the Touch Manager.
  • queueTouchEnd is now called onTouchEnd and invoked by the Touch Manager.
  • queueTouchCancel is now called onTouchCancel and invoked by the Touch Manager.
  • queueMouseDown is now called onMouseDown and invoked by the Mouse Manager.
  • queueMouseMove is now called onMouseMove and invoked by the Mouse Manager.
  • queueMouseUp is now called onMouseUp and invoked by the Mouse Manager.

Each of these handlers used to check the enabled state of the Input Manager, but this now handled directly in the Touch and Mouse Managers instead, leading to less branching and cleaner tests. They also all used to run an IIFE that updated motion on the changed pointers array, but this is now handled directly in the event handler, allowing it to be removed from here.

Because the legacy queue mode is gone, there is no longer any need for the DOM Callbacks:

  • Removed the _hasUpCallback, _hasDownCallback and _hasMoveCallback properties from the Input Manager
  • Removed the processDomCallbacks, addDownCallback, addUpCallback, addMoveCallback, domCallbacks, addDownCallback, addUpCallback and addMoveCallback methods.

Also, CSS cursors can now be set directly:

  • Cursors are now set and reset immediately on the canvas, leading to the removal of _setCursor and _customCursor properties.

The following changes took place in the Input Plugin class:

  • The method processDragEvents has been removed as it's now split across smaller, more explicit methods.
  • processDragDownEvent is a new method that handles a down event for drag enabled Game Objects.
  • processDragMoveEvent is a new method that handles a move event for drag enabled Game Objects.
  • processDragUpEvent is a new method that handles an up event for drag enabled Game Objects.
  • processDragStartList is a new internal method that builds a drag list for a pointer.
  • processDragThresholdEvent is a new internal method that tests when a pointer with drag thresholds can drag.
  • processOverEvents is a new internal method that handles when a touch pointer starts and checks for over events.
  • processOutEvents is a new internal method that handles when a touch pointer stops and checks for out events.

The following changes took place in the Pointer class:

  • Pointer.dirty has been removed as it's no longer required.
  • Pointer.justDown has been removed as it's not used internally and makes no sense under the DOM event system.
  • Pointer.justUp has been removed as it's not used internally and makes no sense under the DOM event system.
  • Pointer.justMoved has been removed as it's not used internally and makes no sense under the DOM event system.
  • The Pointer.reset method has been removed as it's no longer required internally.
  • Pointer.touchstart now has two arguments, the Touch List entry and the Touch Event. The full Touch Event is now stored in Pointer.event (instead of the Touch List entry).
  • Pointer.touchmove now has two arguments, the Touch List entry and the Touch Event. The full Touch Event is now stored in Pointer.event (instead of the Touch List entry).
  • Pointer.touchend now has two arguments, the Touch List entry and the Touch Event. The full Touch Event is now stored in Pointer.event (instead of the Touch List entry).
  • Pointer.touchcancel now has two arguments, the Touch List entry and the Touch Event. The full Touch Event is now stored in Pointer.event (instead of the Touch List entry).

New Features

  • Matter.Factory.velocity is a new method that allows you to set the velocity on a Matter Body directly.
  • Matter.Factory.angularVelocity is a new method that allows you to set the angular velocity on a Matter Body directly.
  • Matter.Factory.force is a new method that allows you to apply a force from a world position on a Matter Body directly.
  • GetBounds.getTopCenter is a new method that will return the top-center point from the bounds of a Game Object.
  • GetBounds.getBottomCenter is a new method that will return the bottom-center point from the bounds of a Game Object.
  • GetBounds.getLeftCenter is a new method that will return the left-center point from the bounds of a Game Object.
  • GetBounds.getRightCenter is a new method that will return the right-center point from the bounds of a Game Object.
  • You can now create a desynchronized 2D or WebGL canvas by setting the Game Config property desynchronized to true (the default is false). For more details about what this means see https://developers.google.com/web/updates/2019/05/desynchronized.
  • The CanvasRenderer can now use the transparent Game Config property in order to tell the browser an opaque background is in use, leading to faster rendering in a 2D context.
  • GameObject.scale is a new property, that exists as part of the Transform component, that allows you to set the horizontal and vertical scale of a Game Object via a setter, rather than using the setScale method. This is handy for uniformly scaling objects via tweens, for example.
  • Base64ToArrayBuffer is a new utility function that will convert a base64 string into an ArrayBuffer. It works with plain base64 strings, or those with data uri headers attached to them. The resulting ArrayBuffer can be fed to any suitable function that may need it, such as audio decoding.
  • ArrayBufferToBase64 is a new utility function that converts an ArrayBuffer into a base64 string. You can also optionally included a media type, such as image/jpeg which will result in a data uri being returned instead of a plain base64 string. *WebAudioSoundManager.decodeAudio is a new method that allows you to decode audio data into a format ready for playback and stored in the audio cache. The audio data can be provided as an ArrayBuffer, a base64 string or a data uri. Listen for the events to know when the data is ready for use.
  • Phaser.Sound.Events#DECODED is a new event emitted by the Web Audio Sound Manager when it has finished decoding audio data.
  • Phaser.Sound.Events#DECODED_ALL is a new event emitted by the Web Audio Sound Manager when it has finished decoding all of the audio data files passed to the decodeAudio method.
  • Phaser.Utils.Objects.Pick is a new function that will take an object and an array of keys and return a new object containing just the keys provided in the array.
  • Text.align and Text.setAlign can now accept justify as a type. It will apply basic justification to multi-line text, adding in extra spaces in order to justify the content. Fix #4291 (thanks @andrewbaranov @Donerkebap13 @dude78GH)
  • Arcade.Events.WORLD_STEP is a new event you can listen to. It is emitted by the Arcade Physics World every time the world steps once. It is emitted after the bodies and colliders have been updated. Fix #4289 (thanks @fant0m)

Updates

  • Zones will now use the new customHitArea property introduced in 3.17 to avoid their hit areas from being resized if you specified your own custom hit area (thanks @rexrainbow)
  • The default BaseShader vertex shader has a new uniform uResolution which is set during the Shader init and load to be the size of the Game Object to which the shader is bound.
  • The default BaseShader vertex shader will now set the fragCoord varying to be the Game Object height minus the y inPosition. This will give the correct y axis in the fragment shader, causing 'inverted' shaders to display normally when using the default vertex code.
  • There was some test code left in the DOMElementCSSRenderer file that caused getBoundingClientRect to be called every render. This has been removed, which increases performance significantly for DOM heavy games.
  • The TimeStep will no longer set its frame property to zero in the resetDelta method. Instead, this property is incremented every step, no matter what, giving an accurate indication of exactly which frame something happened on internally.
  • The TimeStep.step method no longer uses the time value passed to the raf callback, as it's not actually the current point in time, but rather the time that the main thread began at. Which doesn't help if we're comparing it to event timestamps.
  • TimeStep.now is a new property that holds the exact performance.now value, as set at the start of the current game step.
  • Matter.Factory.fromVertices can now take a vertices path string as its vertexSets argument, as well as an array of vertices.
  • GetBounds.prepareBoundsOutput is a new private method that handles processing the output point. All of the bounds methods now use this, allowing us to remove a lot of duplicated code.
  • The PluginManager will now display a console warning if it skips installing a plugin (during boot) because the plugin value is missing or empty (thanks @samme)
  • When creating a Matter Constraint via the Factory you can now optionally provide a length. If not given, it will determine the length automatically from the position of the two bodies.
  • When creating a Matter Game Object you can now pass in a pre-created Matter body instead of a config object.
  • When Debug Draw is enabled for Arcade Physics it will now use Graphics.defaultStrokeWidth to drawn the body with, this makes static bodies consistent with dynamic ones (thanks @samme)
  • Group.name is a new property that allows you to set a name for a Group, just like you can with all other Game Objects. Phaser itself doesn't use this, it's there for you to take advantage of (thanks @samme)
  • Calling ScaleManager.setGameSize will now adjust the size of the canvas element as well. Fix #4482 (thanks @sudhirquestai)
  • Scale.Events.RESIZE now sends two new arguments to the handler: previousWidth and previousHeight. If, and only if, the Game Size has changed, these arguments contain the previous size, before the change took place.
  • The Camera Manager has a new method onSize which is invoked by handling the Scale Manager RESIZE event. When it receives it, it will iterate the cameras it manages. If the camera doesn't have a custom offset and is the size of the game, then it will be automatically resized for you. This means you no longer need to call this.cameras.resize(width, height) from within your own resize handler, although you can still do so if you wish, as that will resize every Camera being managed to the new size, instead of just 'full size' cameras.
  • Graphics.translate has been renamed to Graphics.translateCanvas to make it clearer what it's actually translating (i.e. the drawing buffer, not the Graphics object itself)
  • Graphics.scale has been renamed to Graphics.scaleCanvas to make it clearer what it's actually scaling (i.e. the drawing buffer, not the Graphics object itself)
  • Graphics.rotate has been renamed to Graphics.rotateCanvas to make it clearer what it's actually rotating (i.e. the drawing buffer, not the Graphics object itself)
  • The width and height of an Arc / Circle Shape Game Object is now set to be the diameter of the arc, not the radius (thanks @rexrainbow)
  • LineStyleCanvas now takes an altColor argument which is used to override the context color.
  • LineStyleCanvas now takes an altAlpha argument which is used to override the context alpha.
  • FillStyleCanvas now takes an altAlpha argument which is used to override the context alpha.
  • StaticPhysicsGroup can now take a classType property in its Group Config and will use the value of it, rather than override it. If none is provided it'll default to ArcadeSprite. Fix #4401 (thanks @Legomite)
  • Phaser.Tilemaps.Parsers.Tiled used to run the static function ParseJSONTiled. Parsers.Tiled is now just a namespace, so access the function within it: Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled.
  • Phaser.Tilemaps.Parsers.Impact used to run the static function ParseWeltmeister. Parsers.Impact is now just a namespace, so access the function within it: Phaser.Tilemaps.Parsers.Impact.ParseWeltmeister.
  • Phaser.Tilemaps.Parsers.Tiled.AssignTileProperties is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Tiled.Base64Decode is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Tiled.BuildTilesetIndex is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Tiled.ParseGID is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Tiled.ParseImageLayers is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Tiled.ParseObject is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Tiled.ParseObjectLayers is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Tiled.ParseTileLayers is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Tiled.ParseTilesets is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Tiled.ParseTilesets is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Impact.ParseTileLayers is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Impact.ParseTilesets is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Impact.ParseWeltmeister is now a public static function, available to be called directly.
  • Phaser.Tilemaps.Parsers.Tiled.Pick has been removed. It is now available under Phaser.Utils.Objects.Pick, which is a more logical place for it.
  • You can now call this.scene.remove at the end of a Scene's create method without it throwing an error. Why you'd ever want to do this is beyond me, but you now can (thanks @samme)
  • The Arcade.StaticBody.setSize arguments have changed from (width, height, offsetX, offsetY) to (width, height, center). They now match Dynamic Body setSize and the Size Component method (thanks @samme)
  • When enabling Arcade Physics Body debug it will now draw only the faces marked for collision, allowing you to easily see if a face is disabled or not (thanks @BdR76)
  • Transform.getParentRotation is a new method available to all GameObjects that will return the sum total rotation of all of the Game Objects parent Containers, if it has any.
  • Tween.restart now sets the Tween properties elapsed, progress, totalElapsed and totalProgress to zero when called, rather than adding to existing values should the tween already be running.
  • ArcadePhysics.Body.resetFlags is a new method that prepares the Body for a physics step by resetting the wasTouching, touching and blocked states.
  • ArcadePhysics.Body.preUpdate has two new arguments willStep and delta. If willStep is true then the body will call resetFlags, sync with the parent Game Object and then run one iteration of Body.update, using the provided delta. If false, only the Game Object sync takes place.
  • ArcadePhysics.World.update will now determine if a physics step is going to happen this frame or not. If not, it no longer calls World.step (fix #4529, thanks @ampled). If a step is going to happen, then it now handles this with one iteration of the bodies array, instead of two. It has also inlined a single world step, avoiding branching out. If extra world steps are required this frame (such as in high Hz environments) then World.step is called accordingly.
  • ArcadePhysics.World.postUpdate will no longer call Body.postUpdate on all of the bodies if no World step has taken place this frame.
  • ArcadePhysics.World.step will now increment the stepsLastFrame counter, allowing postUpdate to determine if bodies should be processed should World.step have been invoked manually.

Bug Fixes

  • Tweens created in a paused state couldn't be started by a call to play. Fix #4525 (thanks @TonioParis)
  • If both Arcade Physics circle body positions and the delta equaled zero, the separateCircle function would cause the position to be set NaN (thanks @hizzd)
  • The CameraManager would incorrectly destroy the default Camera in its shutdown method, meaning that if you used a fixed mask camera and stopped then resumed a Scene, the masks would stop working. The default camera is now destroyed only in the destroy method. Fix #4520 (thanks @telinc1)
  • Passing a Frame object to Bob.setFrame would fail, as it expected a string or integer. It now checks the type of object, and if a Frame it checks to make sure it's a Frame belonging to the parent Blitter's texture, and if so sets it. Fix #4516 (thanks @NokFrt)
  • The ScaleManager full screen call had an arrow function in it. Despite being within a conditional block of code it still broke really old browsers like IE11, so has been removed. Fix #4530 (thanks @jorbascrumps @CNDW)
  • Game.getTime would return NaN because it incorrectly accessed the time value from the TimeStep.
  • Text with a fixedWidth or fixedHeight could cause the canvas to be cropped if less than the size of the Text itself (thanks @rexrainbow)
  • Changing the radius of an Arc Game Object wouldn't update the size, causing origin issues. It now updates the size and origin correctly in WebGL. Fix #4542 (thanks @@PhaserEditor2D)
  • Setting padding in a Text style configuration object would cause an error about calling split on undefined. Padding can now be applied both in the config and via setPadding.
  • Tilemap.createBlankDynamicLayer would fail if you provided a string for the tileset as the base tile width and height were incorrectly read from the tileset argument. Fix #4495 (thanks @jppresents)
  • Tilemap.createDynamicLayer would fail if you called it without setting the x and y arguments, even though they were flagged as being optional. Fix #4508 (thanks @jackfreak)
  • RenderTexture.draw didn't work if no x and y arguments were provided, even though they are optional, due to a problem with the way the frame cut values were added. The class has been refactored to prevent this, fixing issues like RenderTexture.erase not working with Groups. Fix #4528 (thanks @jbgomez21 @telinc1)
  • The Grid Game Object wouldn't render in Canvas mode at all. Fix #4585 (thanks @fyyyyy)
  • If you had a Graphics object in the display list immediately after an object with a Bitmap Mask it would throw an error Uncaught TypeError: Cannot set property 'TL' of undefined. Fix #4581 (thanks @Petah @Loonride)
  • Calling Arcade Physics Body.reset on a Game Object that doesn't have any bounds, like a Container, would throw an error about being unable to access getTopLeft. If this is the case, it will now set the position to the given x/y values (thanks Jazz)
  • All of the Tilemaps.Parsers.Tiled static functions are now available to be called directly. Fix #4318 (thanks @jestarray)
  • Arcade.StaticBody.setSize now centers the body correctly, as with the other similar methods. Fix #4213 (thanks @samme)
  • Setting random: false in a Particle Emitter config option no longer causes it to think random is true (thanks @samme)
  • Zone.setSize didn't update the displayOrigin, causing touch events to be inaccurate as the origin was out. Fix #4131 (thanks @rexrainbow)
  • Tween.restart wouldn't restart the tween properly. Fix #4594 (thanks @NokFrt)
  • Looped Tween Timelines would mess-up the tween values on every loop repeat, causing the loop to fail. They now loop correctly due to a fix in the Tween.play method. Fix #4558 (thanks @peteroravec)
  • Timeline.setTimeScale would only impact the Timeline loop and completion delays, not the actively running Tweens. It now scales the time for all child tweens as well. Fix #4164 (thanks @garethwhittaker)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@PhaserEditor2D @samme @Nallebeorn @Punkiebe @rootasjey @Sun0fABeach

- JavaScript
Published by photonstorm almost 7 years ago

phaser - Phaser v3.17.0

Shaders

'Shader' is a new type of Game Object which allows you to easily add a quad with its own shader into the display list, and manipulate it as you would any other Game Object, including scaling, rotating, positioning and adding to Containers. Shaders can be masked with either Bitmap or Geometry masks and can also be used as a Bitmap Mask for a Camera or other Game Object. They can also be made interactive and used for input events.

They work by taking a reference to a Phaser.Display.BaseShader instance, as found in the Shader Cache. These can be created dynamically at runtime, or loaded in via the updated GLSL File Loader:

```javascript function preload () { this.load.glsl('fire', 'shaders/fire.glsl.js'); }

function create () { this.add.shader('fire', 400, 300, 512, 512); } ```

Please see the Phaser 3 Examples GitHub repo for examples of loading and creating shaders dynamically.

  • Display.BaseShader is a new type of object that contain the fragment and vertex source, together with any uniforms the shader needs, and are used when creating the new Shader Game Objects. They are stored in the Shader cache.
  • The Shader Cache this.cache.shader has been updated. Rather than holding plain text fragments, it now holds instances of the new BaseShader objects. As a result, using cache.shader.get(key) will now return a BaseShader instead of a text file.
  • The GLSLFile loader has been updated with new arguments. As well as a URL to the shader file you can also specify if the file is a fragment or vertex shader. It then uses this value to help create or update a BaseShader instance in the shader cache.
  • The GLSLFile loader now supports shader bundles. These allow for multiple shaders to be stored in a single file, with each shader separated by a block of front-matter that represents its contents. Example shader bundles can be found in the Phaser 3 Examples repo.

DOM Elements

DOM Elements have finally left the experimental stage and are now part of the full Phaser release.

DOM Element Game Objects are a way to control and manipulate HTML Elements over the top of your game. In order for DOM Elements to display you have to enable them by adding the following to your game configuration object:

javascript dom { createContainer: true }

When this is added, Phaser will automatically create a DOM Container div that is positioned over the top of the game canvas. This div is sized to match the canvas, and if the canvas size changes, as a result of settings within the Scale Manager, the dom container is resized accordingly.

You can create a DOM Element by either passing in DOMStrings, or by passing in a reference to an existing Element that you wish to be placed under the control of Phaser. For example:

javascript this.add.dom(x, y, 'div', 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser');

The above code will insert a div element into the DOM Container at the given x/y coordinate. The DOMString in the 4th argument sets the initial CSS style of the div and the final argument is the inner text. In this case, it will create a lime colored div that is 220px by 100px in size with the text Phaser in it, in an Arial font.

You should nearly always, without exception, use explicitly sized HTML Elements, in order to fully control alignment and positioning of the elements next to regular game content.

Rather than specify the CSS and HTML directly you can use the load.html File Loader to load it into the cache and then use the createFromCache method instead. You can also use createFromHTML and various other methods available in this class to help construct your elements.

Once the element has been created you can then control it like you would any other Game Object. You can set its position, scale, rotation, alpha and other properties. It will move as the main Scene Camera moves and be clipped at the edge of the canvas. It's important to remember some limitations of DOM Elements: The obvious one is that they appear above or below your game canvas. You cannot blend them into the display list, meaning you cannot have a DOM Element, then a Sprite, then another DOM Element behind it.

You can find lots of examples on using DOM Elements in the Phaser 3 Examples repo.

Geometry and Bitmap Masks

  • Camera.setMask is a new method that allows you to set a geometry or bitmap mask on any camera. The mask can be set to remain fixed in position, or to translate along with the camera. It will impact anything the camera renders. A reference to the mask is stored in the Camera.mask property.
  • Camera.clearMask is a new method that clears a previously set mask on a Camera.
  • There is a new Game Config property input.windowEvents which is true by default. It controls if Phaser will listen for any input events on the Window. If you disable this, Phaser will stop being able to emit events like POINTER_UP_OUTSIDE, or be aware of anything that happens outside of the Canvas re: input.
  • Containers can now contain masked children and have those masks respected, including the mask on the Container itself (if any). Masks work on any depth of child up to 255 children deep.
  • Geometry Masks are now batched. Previously, using the same mask on multiple Game Objects would create brand new stencil operations for every single Game Object, causing performance to tank. Now, the mask is only set if it's different from the previously masked object in the display list, allowing you to mask thousands of Game Objects and retain batching through-out.
  • GeometryMask.setInvertAlpha is a new method that allows you to set the invertAlpha property in a chainable call.
  • Previously, setting a mask on a Particle Emitter wouldn't work (it had to be set on the Emitter Manager instance), even though the mask methods and properties existed. You can now set a geometry or bitmap mask directly on an emitter.
  • The Particle Emitter Manager was missing the Mask component, even though it fully supported masking. The Mask component has now been added. You can now mask the manager, which impacts all emitters you create through it, or a specific emitter. Different emitters can have different masks, although they override the parent mask, if set.
  • You can now apply a Bitmap Mask to a Camera or Container and a Geometry Mask to a child and have it work correctly.
  • WebGLRenderer.maskCount is a new internal property that tracks the number of masks in the stack.
  • WebGLRenderer.maskStack is a new internal array that contains the current mask stack.

Arcade Physics

New Features

  • overlapTiles is a new method that allows you to check for overlaps between a physics enabled Game Object and an array of Tiles. The Tiles don't have to have been enable for collision, or even be on the same layer, for the overlap check to work. You can provide your own process callback and/or overlap callback. This is handy for testing for overlap for a specific Tile in your map, not just based on a tile index. This is available via this.physics.overlapTiles and the World instance.
  • collideTiles is a new method that allows you to check for collision between a physics enabled Game Object and an array of Tiles. The Tiles don't have to have been enable for collision, or even be on the same layer, for the collision to work. You can provide your own process callback and/or overlap callback. There are some limitations in using this method, please consult the API Docs for details, but on the whole, it allows for dynamic collision on small sets of Tile instances. This is available via this.physics.collideTiles and the World instance.
  • overlapRect is a new method that allows you to return an array of all physics bodies within the given rectangular region of the World. It can return dynamic or static bodies and will use the RTree for super-fast searching, if enabled (which it is by default)
  • The Body.setCollideWorldBounds method has two new optional arguments bounceX and bounceY which, if given, will set the World Bounce values for the body.

Updates

  • Body.preUpdate is a new method that is called only once per game step. It resets all collision status properties and syncs the Body with the parent Game Object.
  • Body.update has been rewritten to just perform one single physics step and no longer re-syncs with the Game Object. It can be called multiple times per game step, depending on the World FPS rate.
  • Body.postUpdate has been rewritten to make it more compact. It syncs the body data back to the parent Game Object and is only called once per game step now (previously it was called whenever the Body updated)
  • The World.late Set has been removed and is no longer populated, as it's no longer required.
  • World.update now calls Body.preUpdate just once per game step, then calls Body.update as many times as is required as per the FPS setting, and no longer calls Body.postUpdate at all.
  • World.collideSpriteVsTilemapLayer now returns a boolean if a collision or overlap happens, where-as before it didn't.
  • World.collideSpriteVsTilemapLayerHandler is a new private method that handles all tilemap collision checks.
  • The internal method SeparateTile now has a new argument isLayer which controls if the set comes from a layer or an array.
  • The internal method TileCheckX now has a new argument isLayer which controls if the set comes from a layer or an array.
  • The internal method TileCheckY now has a new argument isLayer which controls if the set comes from a layer or an array.
  • Body.isMoving has been removed as it was never used internally.
  • Body.stopVelocityOnCollide has been removed as it was never used internally.
  • All of the Arcade Physics Components are now available directly under the Phaser.Physics.Arcade.Components namespace. Fix #4440 (thanks @jackfreak)
  • Phaser.Physics.Arcade.Events is now exposed in the namespace, preventing it from erroring if you use them in TypeScript. Fix #4481 (thanks @danielalves)
  • The Matter World configuration value bodyDebugFillColor has been renamed to debugBodyFillColor to be consistent with the rest of the options.
  • The Matter World configuration has a new property: debugStaticBodyColor that sets the static body debug color.

Bug Fixes

  • The Body.delta values are now able to be read and acted upon during a Scene update, due to the new game step flow. This means you can now call this.physics.collide during a Scene update and it will work properly again. Fix #4370 (thanks @NokFrt)
  • ArcadePhysics.furthest now iterates the bodies Set, rather than the RTree, which keeps it working even if the RTree has been disabled.
  • ArcadePhysics.closest now iterates the bodies Set, rather than the RTree, which keeps it working even if the RTree has been disabled.
  • Body.setVelocity caused the speed property to be set to NaN if you didn't provide a y argument.
  • Passing an array of configuration objects to physics.add.group would ignore them and none of the children would be assigned a physics body. Fix #4511 (thanks @rgk)
  • A Body with damping and drag enabled would fail to move if it went from zero velocity to a new velocity inside an update loop. It will now reset its speed accordingly and retain its new velocity (thanks StealthGary)

Facebook Instant Games Plugin

  • The method consumePurchases has been renamed to consumePurchase to bring it in-line with the Facebook API.
  • getProduct is a new method that will return a single Product from the product catalog based on the given Product ID. You can use this to look-up product details based on a purchase list.

New Features

  • A Scene will now emit the new CREATE event after it has been created by the Scene Manager. If the Scene has a create method this event comes after that, so is useful to knowing when a Scene may have finished creating Game Objects, etc. (thanks @jackfreak)
  • Tilemap.removeTile is a new method that allows you to remove a tile, or an array of tiles, by passing in references to the tiles themselves, rather than coordinates. The tiles can be replaced with new tiles of the given index, or removed entirely, and the method can optionally recalculate interesting faces on the layer.
  • TweenManager.remove is a new method that immediately removes the given Tween from all of its internal arrays.
  • Tween.remove is a new method that immediately removes the Tween from the TweenManager, regardless of what state the tween is in. Once called the tween will no longer exist within any internal TweenManager arrays.
  • SceneManager.isPaused is a new method that will return if the given Scene is currently paused or not (thanks @samme)
  • ScenePlugin.isPaused is a new method that will return if the given Scene is currently paused or not (thanks @samme)
  • TextureManager.removeKey is a new method that will remove a key from the Texture Manager without destroying the texture itself.
  • Matter.World.resetCollisionIDs is a new method that will reset the 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 (thanks @clesquir)
  • RenderTexture has two new optional constructor arguments key and frame. This allows you to create a RenderTexture pre-populated with the size and frame from an existing texture (thanks @TadejZupancic)
  • GameObjects.Components.PathFollower is a new component that manages any type of Game Object following a path. The original Path Follower Game Object has been updated to use this new component directly, but it can be applied to any custom Game Object class.
  • Tilemap.removeLayer is a new method that allows you to remove a specific layer from a Tilemap without destroying it.
  • Tilemap.destroyLayer is a new method that allows you to destroy a layer and remove it from a Tilemap.
  • Tilemap.renderDebugFull is a new method that will debug render all layers in the Tilemap to the given Graphics object.
  • Geom.Intersects.GetCircleToCircle is a new function that will return the point/s of intersection between two circles (thanks @florianvazelle)
  • Geom.Intersects.GetCircleToRectangle is a new function that will return the point/s of intersection between a circle and a rectangle (thanks @florianvazelle)
  • Geom.Intersects.GetLineToCircle is a new function that will return the point/s of intersection between a line and a circle (thanks @florianvazelle)
  • Geom.Intersects.GetLineToRectangle is a new function that will return the point/s of intersection between a line and a rectangle (thanks @florianvazelle)
  • Geom.Intersects.GetRectangleToRectangle is a new function that will return the point/s of intersection between two rectangles (thanks @florianvazelle)
  • Geom.Intersects.GetRectangleToTriangle is a new function that will return the point/s of intersection between a rectangle and a triangle (thanks @florianvazelle)
  • Geom.Intersects.GetTriangleToCircle is a new function that will return the point/s of intersection between a triangle and a circle (thanks @florianvazelle)
  • Geom.Intersects.GetTriangleToLine is a new function that will return the point/s of intersection between a triangle and a line (thanks @florianvazelle)
  • Geom.Intersects.GetTriangleToTriangle is a new function that will return the point/s of intersection between two triangles (thanks @florianvazelle)
  • Size.setCSS is a new method that will set the Size components width and height to the respective CSS style properties of the given element.
  • CSSFile is a new Loader FileType that allows you to load css into the current document via the normal Phaser Loader, using the load.css method. As such, you can chain it with other load calls, load via config, use as part of a pack load or any other option available to all loader filetypes. The CSS is applied immediately to the document.
  • MultiScriptFile is a new Loader FileType that allows you to load multiple script files into the document via the Phaser Loader, using the new load.scripts method. The difference between this and load.script is that you must pass an array of script file URLs to this method and they will be loaded in parallel but processed (i.e. added to the document) in the exact order specified in the array. This allows you to load a bundle of scripts that have dependencies on each other.
  • Key.getDuration is a new method that will return the duration, in ms, that the Key has been held down for. If the Key isn't down it will return zero.
  • The Container.setScrollFactor method has a new optional argument updateChildren. If set, it will change the scrollFactor values of all the Container children as well as the Container. Fix #4466 #4475 (thanks @pinkkis @enriqueto)
  • There is a new webpack config FEATURE_SOUND which is set to true by default, but if set to false it will exclude the Sound Manager and all of its systems from the build files. Fix #4428 (thanks @goldfire)
  • Scene.Systems.renderer is a new property that is a reference to the current renderer the game is using.
  • Utils.Objects.SetValue is a new function that allows you to set a value in an object by specifying a property key. The function can set a value to any depth by using dot-notation for the key, i.e. SetValue(data, 'world.position.x', 100).
  • WebGLRenderer.glFuncMap is a new object, populated during the init method, that contains uniform mappings from key to the corresponding gl function, i.e. mat2 to gl.uniformMatrix2fv.
  • BaseCache.getKeys is a new method that will return all keys in use in the current cache, i.e. this.cache.shader.getKeys().

Updates

  • Removed all references to CocoonJS from the API, including in the Device.OS object and elsewhere, as Cocoon is no longer.
  • The MouseManager and TouchManager now use separate handlers for the Window level input events, which check to see if the canvas is the target or not, and redirect processing accordingly.
  • AnimationManager.generateFrameNumbers can now accept a start number greater than the end number, and will generate them in reverse (thanks @cruzdanilo)
  • The return from the ScenePlugin.add method has changed. Previously, it would return the ScenePlugin, but now it returns a reference to the Scene that was added to the Scene Manager, keeping it in-line with all other add methods in the API. Fix #4359 (thanks @BigZaphod)
  • The PluginManager.installScenePlugin method has a new optional boolean parameter fromLoader which controls if the plugin is coming in from the result of a Loader operation or not. If it is, it no longer throws a console warning if the plugin already exists. This fixes an issue where if you return to a Scene that loads a Scene Plugin it would throw a warning and then not install the plugin to the Scene.
  • The Scale Manager has a new event FULLSCREEN_FAILED which is fired if you try to enter fullscreen mode, but the browser rejects it for some reason.
  • The ScaleMode Component has been removed from every Game Object, and along with it the scaleMode property and setScaleMode method. These did nothing anyway as they were not hooked to the render pipeline and scale mode should be set on the texture, not the Game Object. Fix #4413 (thanks @jcyuan)
  • The Clock.now property value is now synced to be the TimeStep.time value when the Clock plugin boots and is no longer Date.now() until the first update (thanks @Antriel)
  • Graphics.strokePoints has renamed the second argument from autoClose to closeShape. There is also a new third argument closePath, which defaults to true and automatically closes the path before stroking it. The endIndex argument is now the fourth argument, instead of the third.
  • Graphics.fillPoints has renamed the second argument from autoClose to closeShape. There is also a new third argument closePath, which defaults to true and automatically closes the path before filling it. The endIndex argument is now the fourth argument, instead of the third.
  • Calling Texture.destroy will now call TextureManager.removeKey to ensure the key is removed from the manager, should you destroy a texture directly, rather than going via TextureManager.remove. Fix #4461 (thanks @BigZaphod)
  • SpriteSheetFromAtlas now adds in a __BASE entry for the Sprite Sheet it creates, keeping it consistent with the other frame parsers (thanks @Cirras)
  • The from and to properties in the PathFollower Config can now be used to set the span of the follow duration (thanks @kensleebos)
  • Graphics.lineFxTo and Graphics.moveFxTo have been removed as they were not being rendered anyway.
  • You can now use "infinite" tilemaps as created in Tiled v1.1 and above. Support is basic in that it takes the chunk data and builds one giant map from it. However, at least you are still able to now load and use infinite maps, even if they don't chunk during the game (thanks @Upperfoot)
  • MapData.infinite is a new boolean that controls if the map data is infinite or not.
  • DynamicTilemapLayer.destroy will now remove the layer from the Tilemap it belongs to, clearing it from the layers array. Fix #4319 (thanks @APXEOLOG)
  • StaticTilemapLayer.destroy will now remove the layer from the Tilemap it belongs to, clearing it from the layers array. Fix #4319 (thanks @APXEOLOG)
  • DynamicTilemapLayer.destroy has a new optional boolean argument removeFromTilemap which will control if the layer is removed from the parent map or not.
  • StaticTilemapLayer.destroy has a new optional boolean argument removeFromTilemap which will control if the layer is removed from the parent map or not.
  • Tilemap.copy now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.fill now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.forEachTile now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.putTilesAt now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.randomize now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.calculateFacesAt now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.renderDebug now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.replaceByIndex now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.setCollision now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.setCollisionBetween now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.setCollisionByProperty now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.setCollisionByExclusion now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.setCollisionFromCollisionGroup now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.setTileIndexCallback now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.setTileLocationCallback now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.shuffle now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.swapByIndex now actually returns null if an invalid layer was given, as per the docs.
  • Tilemap.weightedRandomize now actually returns null if an invalid layer was given, as per the docs.
  • BaseCamera.cameraManager is a new property that is a reference to the Camera Manager, set in the setScene method.
  • CameraManager.default is a new property that contains a single un-transformed instance of a Camera, that exists outside of the camera list and doesn't render. It's used by other systems as a default camera matrix.
  • The Graphics Game Object now has 3 new Transform Matrix instances called _tempMatrix1 to _tempMatrix3, which are used by it during the WebGL Rendering process. This is because Graphics objects can be used as Geometry Masks, which need to retain their own matrix state mid-render of another object, so cannot share the renderer temp matrices that other Game Objects can use. This also indirectly fixes an issue where masked children (such as emitters or container children) would get incorrect camera scroll values.
  • The Key method signature has changed. It now expects to receive a reference to the KeyboardPlugin instance that is creating the Key as the first argument. This is now stored in the new Key.plugin property, and cleared in destroy.
  • KeyboardPlugin.removeKey has a new optional argument destroy that will, if set, destroy the Key object being removed from the plugin.
  • InteractiveObject.customHitArea is a new property that records if the hitArea for the Interactive Object was created based on texture size (false), or a custom shape (true)
  • A Camera will pause following a Game Object for the duration of the Camera Pan Effect, as the two will clash over the Camera scroll position (thanks fruitbatinshades).
  • ParseXMLBitmapFont has now been exposed as a static function on the BitmapText object, so you can access it easily from your own code (thanks @jcyuan)
  • The math used in the circle to circle Arcade Physics collision has been updated to better handle horizontal collision, giving a more realistic response. Fix #4256 (thanks @akuskis @JeSuisUnCaillou)

Bug Fixes

  • The parent bounds are reset when exiting fullscreen mode in the Scale Manager. This fixes an issue when leaving fullscreen mode by pressing ESC (instead of programmatically) would leave the canvas in the full screen size. Fix #4357 (thanks @khutchins and @HeyStevenXu)
  • GetAdvancedValue now uses the correct Math RND reference, which means anything that used the randInt or randFloat features of this function, such as creating a Sprite from a Config object, or Bitmap Text sizing, will no longer throw an error about a null object reference. Fix #4369 (thanks @sanadov)
  • Trying to enter Fullscreen mode on Android / Chrome, or iOS / Safari, would throw an error regarding an unhandled Promise and a failure to invoke the event from a user gesture. This has been tightened up, using a proper Promise handler internally and the documentation clarified to explicitly say that you must call the function from a pointerup handler, and not pointerdown. Fix #4355 (thanks @matrizet)
  • Camera fadeIn and fadeOut would sometimes leave a very low alpha-valued rectangle rendering to the camera. Fix #3833 (thanks @bdaenen)
  • Actions.Spread would only use the min value to work out the step value but not apply it to the property being set (thanks @galman33)
  • Calling Tween.pause returns the Tween instance, however, if it was already paused, it would return undefined, causing problems when chaining Tween methods (thanks @kyranet)
  • Calling TweenManager.makeActive returns the TweenManager instance, however, if you create a tween externally and call makeActive with it, this would return undefined.
  • Setting the fixedWidth and / or fixedHeight properties in the configuration of a Text would be ignored, they were only supported when calling the setFixedSize method. They now work via either option. Fix #4424 (thanks @rexrainbow)
  • When calculating the width of a Text object for word wrapping it would ignore the extra spaces added from the wrap. It now accounts for these in the width. Fix #4187 (thanks @rexrainbow)
  • Utils.Array.Add would act incorrectly when adding an object into an array in which it already belonged. This would manifest if, for example, adding a child into a display list it was already a part of. Fix #4411 (thanks @mudala @LoolzRules)
  • Tile.getCenterX and Tile.getCenterY would return the wrong values for tiles on scaled layers. Fix #3845 (thanks @oloflarsson @florianvazelle)
  • Camera.startFollow will now ensure that if the Camera is using bounds that the scrollX and scrollY values set after first following the Game Object do not exceed the bounds (thanks @snowbillr)
  • Creating a Tween with a duration of zero would cause the tweened object properties to be set to NaN. Now they will tween for one single frame before being set to progress 1. Fix #4235 (thanks @BigZaphod)
  • The First frame of a Texture would take on the appearance of the second frame in a Sprite Sheet created from trimmed Texture Atlas frames. Fix #4088 (thanks @Cirras)
  • Tween.stop assumed that the parent was the TweenManager. If the Tween has been added to the Timeline, that was not true and the stop method crashed (thanks @TadejZupancic)
  • Calling Tween.restart multiple times in a row would cause the tween to freeze. It will now disregard all additional calls to restart if it's already in a pending state (thanks @rgk)
  • Tween Timelines would only apply the delay value of a child tween once and not on loop. Fix #3841 (thanks @Edwin222 @Antriel)
  • Texture.add will no longer let you add a frame to a texture with the same name or index as one that already exists in the texture. Doing so will now return null instead of a Frame object, and the frameTotal will never be incremented. Fix #4459 (thanks @BigZaphod)
  • The InputPlugin will now dispatch an update event, allowing the Gamepad Plugin to update itself every frame, regardless of DOM events. This allows Gamepads to work correctly again. Fix #4414 (thanks @CipSoft-Components)
  • Calling Tween.play on a tween that had already finished and was pending removal will stop the tween from getting stuck in an isPlaying state and will restart the tween again from the beginning. Calling play on a Tween that is already playing does nothing. Fix #4184 (thanks @SamCode)
  • Declared Audio.dataset, which fixes Internet Explorer 10 crashing when trying to access the dataset property of the object (thanks @SirLink)
  • The InputManager.update method is now called every frame, as long as a native DOM event hasn't already fired it, which allows things like setPollRate to work again. Fix #4405 (thanks @Shucki)
  • Pointer.getDuration would only return zero until the pointer was released, or moved (basically any action that generated a DOM event). It now returns the duration regardless of the DOM events. Fix #4444 (thanks @plazicx)
  • Keyboard.UpDuration has been changed so the duration being checked is now against the current game clock. This means you can use it to check if a Key was released within duration ms ago, based on the time now, not the historic value of the Key.
  • Keyboard.DownDuration has been changed so the duration being checked is now against the current game clock. This fixes an issue where it couldn't be used while the Key was actively being held down. Fix #4484 (thanks @belen-albeza)
  • Keys would lose track of the state of a Scene when the Scene became paused. They're now updated regardless, stopping them from getting stuck if you pause and resume a Scene while holding them down. Fix #3822 (thanks @DannyT)
  • Changing any aspect of a Text object, such as the font size or content, wouldn't update its hitArea if it had been enabled for input, causing it to carry on using the old hit area size. Now, as long as the Text was created without a custom hitArea, the hitArea size will be changed to match the new texture size on update. If you have provided your own custom hitArea shape, you need to modify it when the Text changes size yourself. Fix #4456 (thanks @thanh-taro and @rexrainbow)
  • Camera.clearRenderToTexture will check to see if the Scene is available before proceeding, avoiding potential errors when a Camera is destroyed multiple times during a Scene shutdown.
  • Destroying a Game object during its pointerup event handler on a touch device will no longer cause Uncaught TypeError: Cannot read property 'localX' of undefined. All InputPlugin process handlers now check to see if the Game Object has been destroyed at any stage and abort if it has. Fix #4463 (thanks @PatrickSachs)
  • InputPlugin.clear has a new argument skipQueue which is used to avoid clearing a Game Object twice. This, combined with the fix for 4463 means you will no longer get a Cannot read property 'dragState' error if you destroy a Game Object enabled for drag where another draggable object exists. Fix #4228 (thanks @YannCaron)
  • UpdateList.remove will now move the removed child to the internal _pendingRemoval array, instead of slicing it directly out of the active list. The pending list is cleared at the start of the next game frame. Fix #4365 (thanks @jcyuan)
  • Setting pixelPerfect when input enabling a Container would cause it to crash, because Containers don't have a texture to check. It will now throw a run-time warning and skip the Container for input. You should use a custom input callback instead. Fix #4492 (thanks @BigZaphod)
  • Setting fixedWidth and fixedHeight on a Text object will now clamp the size of the canvas being created, as well as the width and height properties of the Text object itself (thanks @rexrainbow)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@sky-coding @G-Rath @S4n60w3n @rootasjey @englercj @josephmbustamante @Jason-Cooke @Zamiell @krzysztof-grzybek @S4n60w3n @m31271n @peterellisjones @martinlindhe @TylerMorley @samme @schomatis @BeLi4L @hizzd @OmarShehata @antoine-pous @digitsensitive

Also, thanks to @Osmose there is a new Dashing config added to the Phaser 3 Docs Repo, with a new command build-docset which will build a Dash compatible docset for those who like to use Dash for their docs.

- JavaScript
Published by photonstorm about 7 years ago

phaser - Phaser v3.16.2

This is point release primarily fixes a few important issues that surfaced in 3.16.0. Please be sure to read the Change Log if you are coming from a version < 3.16.0 as it contains lots of important updates.

Matter Pointer Constraint Changes

The following changes all effect the Matter JS Pointer Constraint class:

  • Pointer handling has been changed to make more sense. In the previous version, pressing down and then moving the Pointer over a body would start it being dragged, even if the pointer was pressed down well outside of the body bounds. Now, a body can only be dragged by actually pressing down on it, or any of its parts, which is more in-line with how input events should work.
  • Previously, releasing ANY pointer would stop an object being dragged, even if it wasn't the one actually dragging a body, as in a multi-touch game. Bodies are now bound to the pointer which started their drag and only the release of that pointer will stop them.
  • There is a new Matter Physics Event DRAG_START which is emitted by a Pointer Constraint when it starts dragging a body. Listen for this event from the Matter World instance.
  • There is a new Matter Physics Event DRAG which is emitted by a Pointer Constraint as it drags a body. Listen for this event from the Matter World instance.
  • There is a new Matter Physics Event DRAG_END which is emitted by a Pointer Constraint when it stops dragging a body. Listen for this event from the Matter World instance.
  • The camera property can no longer be set in the config object. Instead it is set every time the Pointer is pressed down on a Body, this resolves issues where you have a multi-camera Scene and want to drag a body in the non-main camera.
  • body is a new property that holds a reference to the Body being dragged, if any.
  • part is a new property that holds a reference to the Body part that was clicked on which started the drag.
  • The internal getBodyPart method has been renamed to hitTestBody to more accurately reflect what it does.
  • The class no longer listens for the pointer up event, instead of tracks the active pointer and waits for that to be released. This has reduced the complexity and size of the update method considerably.
  • stopDrag is a new method that allows you to manually stop an object being dragged, even if the pointer isn't released.
  • This class now has 100% JSDocs.

Updates

  • TileSprite.setTileScale has been updated so that the y argument is optional and set to match the x argument, like setScale elsewhere in the API.
  • InputManager.time is a new property that holds the most recent time it was updated from the Game step, which plugins can access.
  • InputManager.preStep is a new method that populates some internal properties every step.
  • KeyboardPlugin.time has moved from being a property to being a getter, which returns the time from the InputManager.
  • The scale property has been added to the Scene class (thanks @strangeweekend)
  • Matter.World.remove now uses the Composite.remove method internally. Previously, it used Composite.removeBody which only allowed it to remove bodies from the simulation. Now, it can remove any type of Matter object.
  • When the Matter World creates its wall bounds, the left and right walls now extend further up and down than before, so that in a 4-wall setting there are no gaps in the corners, which previously allowed for fast moving objects that hit a corner intersection point to sometimes travel through it.
  • Touch inputs will now trigger a POINTER_OUT event if they leave the game (i.e. are released), where-as before they would only trigger the POINTER_UP event. Now, both happen (thanks @rgk)

Bug Fixes

  • The Mesh.setAlpha method has been restored, even though it's empty and does nothing, to prevent runtime errors when adding a Mesh or Quad object to a Container. Fix #4338 #4343 (thanks @pfdtravalmatic @charmingny)
  • KeyboardPlugin.checkDown would always fail if using the new event system, because the time value it was checking wasn't updated.
  • Entering Fullscreen mode in the Scale Manager and then pressing ESC would leave the injected fullsceen div in the DOM, causing it to throw a node insertion failure the second time you wanted to enter fullscreen mode. Fix #4352 (thanks @ngdevr)
  • Due to the changes in the Input event system, the GAME_OUT event would never fire unless the input system was in legacy mode. The OUT and OVER handlers have been refactored and will now fire as soon as the DOM event happens. As a result the InputManager._emitIsOverEvent property has been removed, as the native event is sent directly to the handler and doesn't need storing locally any more. Fix #4344 (thanks @RademCZ)
  • Added Zone.setBlendMode method as a NOOP function, fixing a bug where if you added a Zone to a Container when running under Canvas it would fail. Fix #4295 (thanks @emanuel15)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@maretana @CipSoft-Components @brian-lui

- JavaScript
Published by photonstorm over 7 years ago

phaser - Phaser v3.16.1

Phaser 3.16 is a massive update. The single largest in the history of Phaser 3 and it contains breaking changes. If you're upgrading from an earlier version please do check the log entries below.

Please note: there is no difference between 3.16.0 and 3.16.1. The version bump was just to get around a stupid npm semver policy.

Important Namespace Changes

  • The Phaser.Boot namespace has been renamed to Phaser.Core. As a result, the boot folder has been renamed to core. This impacts the TimeStep class and VisibilityHandler function, which have been moved to be under the new namespace.
  • The Phaser.Animations namespace was incorrectly exposed in the Phaser entrypoints as Animation (note the lack of plural). This means that if you are creating any custom classes that extend Animation objects using the Phaser namespace, then please update them from Phaser.Animation to Phaser.Animations, i.e. Phaser.Animation.AnimationFrame to Phaser.Animations.AnimationFrame. This doesn't impact you if you created animations directly via the Animation Manager.
  • The keyed Data Manager change data event string has changed from changedata_ to changedata- to keep it consistent with other keyed events. Note the change from _ to -.
  • The Keyboard Plugin keydown dynamic event string has changed from keydown_ to keydown- to keep it consistent with other keyed events. Note the change from _ to -.
  • The Keyboard Plugin keyup dynamic event string has changed from keyup_ to keyup- to keep it consistent with other keyed events. Note the change from _ to -.
  • The texturesready event emitted by the Texture Manager has been renamed to ready.
  • The loadcomplete event emitted by the Loader Plugin has been renamed to postprocess to be reflect what it's used for.
  • Game Objects used to emit a collide event if they had an Arcade Physics Body with onCollide set, that collided with a Tile. This has changed. The event has been renamed to tilecollide and you should now listen for this event from the Arcade Physics World itself: this.physics.world.on('tilecollide'). Game Objects no longer emit this event.
  • Game Objects used to emit an overlap event if they had an Arcade Physics Body with onOverlap set, that overlapped with a Tile. This has changed. The event has been renamed to tileoverlap and you should now listen for this event from the Arcade Physics World itself: this.physics.world.on('tileoverlap'). Game Objects no longer emit this event.
  • The function Phaser.Physics.Impact.SeperateX has been renamed to SeparateX to correct the spelling mistake.
  • The function Phaser.Physics.Impact.SeperateY has been renamed to SeparateY to correct the spelling mistake.
  • The ended event in WebAudioSound has been renamed to complete to make it more consistent with the rest of the API.
  • The ended event in HTML5AudioSound has been renamed to complete to make it more consistent with the rest of the API.
  • The Phaser.Utils.Objects namespace was incorrectly exposed in the Phaser entrypoints as Object (note the lack of plural), this has now been fixed so all associated functions are properly namespaced.
  • Phaser.GameObjects.Blitter.Bob has been renamed to Phaser.GameObjects.Bob to avoid namespace conflicts in TypeScript.
  • Phaser.GameObjects.Text.TextStyle has been renamed to Phaser.GameObjects.TextStyle to avoid namespace conflicts in TypeScript.

Important Changes to the Input System

In Phaser 3.15 and earlier the Input system worked using an event queue. All native DOM input events, such as from the Mouse, Touch or Keyboard, were picked up by event handlers and stored in a queue within the Input Manager. This queue was then processed during the next game step, all the events were dealt with and then it was cleared, ready to receive more events. As they were processed, the internal Phaser events such as pointerdown or keyup were dispatched to your game code.

This worked fine in that you were able to guarantee exactly when the events would arrive, because it was always at the same time in the game step. However, it had the side effect of you not being able to do things like open external browser windows, or go into Full Screen mode, during your event handlers - because they weren't "real" events, so didn't pass the browser security checks. To this end, methods like addUpCallback were added to try and provide this support (although it was never possible for keyboard events).

In 3.16 this has changed. The DOM Events now trigger the respective internal events immediately, in the same invocation. So if you click on the canvas, the pointerdown event you receive in your game is still part of the 'native' event handler, so you're now free to do things like go into full screen mode, or open external windows, without any browser warnings or work-arounds.

It does, however, mean that the point at which these handlers are called is no longer always consistent, and is no longer bound to the speed of the Request Animation Frame update. We've tested as much as possible, and so far, things carry on working as before. We've noticed a slight increase in responsiveness, due to the removal of the fractional delay in processing the events, which feels good. However, if for whatever reason this change has broken your game then you're able to easily switch back to the previous version. In your Game Config, create an input object and give it the property queue: true. This will tell Phaser to use the legacy event queue system.

Please note that we will remove this legacy system in the near future. So, please try and adapt your games to use the new system. If you've found an edge-case where something breaks because of it, please report it so we can look into it.

As a result of this change, the following are now deprecated:

  • InputPlugin.addUpCallback method.
  • InputPlugin.addDownCallback method.
  • InputPlugin.addMoveCallback method.
  • InputManager.queue property.
  • InputManager.domCallbacks property.
  • InputManager._hasUpCallback property.
  • InputManager._hasDownCallback property.
  • InputManager._hasMoveCallback property.
  • InputManager.processDomCallbacks method.
  • InputManager.addUpCallback method.
  • InputManager.addDownCallback method.
  • InputManager.addMoveCallback method.

keydown and keyup changes

Due to unification across the event system, the keydown_ and keyup_ dynamic event strings have changed.

  • In all cases the keydown_KEY event name has changed to keydown-KEY. Note the change from an underscore to a hyphen.
  • In all cases the keyup_KEY event name has changed to keyup-KEY. Note the change from an underscore to a hyphen.

You should update your game code accordingly.

Keyboard Input - New Features

The specificity of the Keyboard events has been changed to allow you more control over event handling. Previously, the Keyboard Plugin would emit the global keydown-CODE event first (where CODE was a keycode string, like keydown-A), then it would emit the global keydown event. In previous versions, Key objects, created via this.input.keyboard.addKey(), didn't emit events.

The Key class now extends EventEmitter and emits two new events directly: down and up. This means you can listen for an event from a Key you've created, i.e.: yourKey.on('up', handler).

The order has also now changed. If it exists, the Key object will dispatch its down event first. Then the Keyboard Plugin will dispatch keydown_CODE and finally the least specific of them all, keydown will be dispatched.

You also now have the ability to cancel this at any stage either on a local or global level. All event handlers are sent an event object which you can call event.stopImmediatePropagation() on. This will immediately stop any further listeners from being invoked in the current Scene. Therefore, if you call stopImmediatePropagation() in the Key.on handler, then the Keyboard Plugin will not emit either the keydown-CODE or keydown global events. You can also call stopImmediatePropagation() during the keydown-CODE handler, to stop it reaching the global keydown handler. As keydown is last, calling it there has no effect.

There is also the stopPropagation() function. This works in the same way as stopImmediatePropagation but instead of being local, it works across all of the Scenes in your game. For example, if you had 3 active Scenes (A, B and C, with A at the top of the Scene list), all listening for the same key, calling stopPropagation() in Scene A would stop the event from reaching any handlers in Scenes B or C. Remember that events flow down the Scene list from top to bottom. So, the top-most rendering Scene in the Scene list has priority over any Scene below it.

All the above also works for keyup events.

New in 3.16 is the ability to receive a global keydown or keyup event from any key on the keyboard. Previously, it would only emit the event if it came from one of the keys listed in the KeyCodes file. Now, those global events will fire for any key, regardless of location.

Keyboard Captures

Key capturing is the way in which you stop a keyboard DOM event from activating anything else in the browser by calling preventDefault on it. For example, in tall web pages, pressing the SPACE BAR causes the page to scroll down. Obviously, if this is also the fire or jump button in your game, you don't want this to happen. So the key needs to be 'captured' to prevent it. Equally, you may wish to also capture the arrow keys, for similar reasons. Key capturing is done on a global level. If you set-up the capture of a key in one Scene, it will be captured globally across the whole game.

In 3.16 you now do this using the new KeyboardPlugin.addCapture method. This takes keycodes as its argument. You can either pass in a single key code (i.e. 32 for the Space Bar), an array of key codes, or a comma-delimited string - in which case the string is parsed and each code it can work out is captured.

To remove a capture you can use the KeyboardPlugin.removeCapture method, which takes the same style arguments as adding captures. To clear all captures call KeyboardPlugin.clearCaptures. Again, remember that these actions are global.

You can also temporarily enable and disable capturing using KeyboardPlugin.enableGlobalCapture and KeyboardPlugin.disableGlobalCapture. This means if you set-up a bunch of key captures, but then need to disable them all for a while (perhaps you swap focus to a DOM text field), you can call disableGlobalCapture to do this, and when finished in the DOM you can enable captures again with enableGlobalCapture, without having to clear and re-create them all.

Default captures can be defined in the Game Config in the input.keyboard.captures object. The captures are actually stored in the KeyboardManager class. The KeyboardPlugin is just a proxy to methods in the Keyboard Manager, but is how you should interface with it.

  • KeyboardPlugin.addCapture is a new method that allows you to define a set of keycodes to have the default browser behaviors disabled on.
  • KeyboardPlugin.removeCapture is a new method that removes specific previously set key captures.
  • KeyboardPlugin.clearCaptures is a new method that removes all key captures.
  • KeyboardPlugin.getCaptures is a new method that returns an array of all current key captures.
  • KeyboardPlugin.enableGlobalCapture is a new method that enables any key captures that have been created.
  • KeyboardPlugin.disableGlobalCapture is a new method that disables any key captures that have been created, without removing them from the captures list.
  • KeyboardPlugin.addKey has a new boolean argument enableCapture, which is true by default, that will add a key capture for the Key being created.
  • KeyboardPlugin.addKeys has a new boolean argument enableCapture, which is true by default, that will add a key capture for any Key created by the method.

Other Keyboard Updates and Fixes

  • There is a new class called KeyboardManager. This class is created by the global Input Manager if keyboard access has been enabled in the Game config. It's responsible for handling all browser keyboard events. Previously, the KeyboardPlugin did this which meant that every Scene that had its own Keyboard Plugin was binding more native keyboard events. This was causing problems with parallel Scenes when needing to capture keys. the KeyboardPlugin class still exists, and is still the main point of interface when you call this.input.keyboard in a Scene, but DOM event handling responsibility has been taken away from it. This means there's now only one set of bindings ever created, which makes things a lot cleaner.
  • There is a new Game and Scene Config setting input.keyboard.capture which is an array of KeyCodes that the Keyboard Plugin will capture all non-modified key events on. By default it is empty. You can populate it in the config, or use the new capture methods.
  • The Keyboard Manager will now call preventDefault only on non-modified key presses, stopping the keyboard event from hitting the browser. Previously, capturing the R key, for example, would block a CTRL+R page reload, but it now ignores it because of the key modifier.
  • If the browser Window loses focus, either from switching to another app, or another tab, all active Keys will be reset. This prevents issues with keys still reporting as being held down after leaving the game and returning to it again. Fix #4134 (thanks @Simplonium)
  • Key.emitOnRepeat is a new boolean property that controls if the 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).
  • Key.setEmitOnRepeat is a new chainable method for setting the emitOnRepeat property.
  • The KeyboardPlugin.addKeys method has a new optional boolean emitOnRepeat which sets that property on all Key objects it creates as part of the call. It defaults to false.
  • The KeyboardPlugin.addKey method has a new optional boolean emitOnRepeat which sets that property on the Key object it creates. It defaults to false.
  • The Key class now extends EventEmitter and emits two events directly: down and up. This means you can listen for an event from a Key you've created, i.e.: yourKey.on('up', handler).
  • The following Key Codes have been added, which include some missing alphabet letters in Persian and Arabic: SEMICOLON_FIREFOX, COLON, COMMA_FIREFOX_WINDOWS, COMMA_FIREFOX, BRACKET_RIGHT_FIREFOX and BRACKET_LEFT_FIREFOX (thanks @wmateam)
  • Key.onDown is a new method that handles the Key being pressed down, including down repeats.
  • Key.onUp is a new method that handles the Key being released.
  • Key.destroy is a new method that handles Key instance destruction. It is called automatically in KeyboardPlugin.destroy.
  • The Key.preventDefault property has been removed. This is now handled by the global keyboard capture methods.
  • Key.metaKey is a new boolean property which indicates if the Meta Key was held down when the Key was pressed. On a Mac the Meta Key is Command. On a Windows keyboard, it's the Windows key.
  • InputManager.keyboard is a new property that instantiates the global Keyboard Manager, if enabled in the game config.
  • The KeyboardPlugin.addKey method has a new boolean property enableCapture which automatically prevents default on the Key being created.
  • The KeyboardPlugin.addKeys method has a new boolean property enableCapture which automatically prevents default on Keys being created.
  • Phaser.Input.Keyboard.ProcessKeyDown has been removed as it's no longer required, Key.onDown handles it instead.
  • Phaser.Input.Keyboard.ProcessKeyUp has been removed as it's no longer required, Key.onUp handles it instead.
  • The Keyboard Manager has a property called captures which is an array of keycodes, as populated by the Game Config. Any key code in the array will have preventDefault called on it if pressed.
  • KeyboardPlugin.manager is a new property that references the Keyboard Manager and is used internally.
  • KeyboardPlugin.target has been removed as it's no longer used by the class.
  • KeyboardPlugin.queue has been removed as it's no longer used by the class.
  • KeyboardPlugin.onKeyHandler has been removed as it's no longer used by the class.
  • KeyboardPlugin.startListeners has been removed as it's no longer used by the class.
  • KeyboardPlugin.stopListeners has been removed as it's no longer used by the class.

Mouse and Touch Input - New Features, Updates and Fixes

  • The Mouse Manager class has been updated to remove some commented out code and refine the startListeners method.
  • When enabling a Game Object for input it will now use the width and height properties of the Game Object first, falling back to the frame size if not found. This stops a bug when enabling BitmapText objects for input and it using the font texture as the hit area size, rather than the text itself.
  • Pointer.smoothFactor is a float-value that allows you to automatically apply smoothing to the Pointer position as it moves. This is ideal when you want something smoothly tracking a pointer in a game, or are need a smooth drawing motion for an art package. The default value is zero, meaning disabled. Set to a small number, such as 0.2, to enable.
  • Config.inputSmoothFactor is a new property that allows you to set the smoothing factor for all Pointers the game creates. The default value is zero, which is disabled. Set in the game config as input: { smoothFactor: value }.
  • InputManager.transformPointer has a new boolean argument wasMove, which controls if the pointer is being transformed after a move or up/down event.
  • Pointer.velocity is a new Vector2 that contains the velocity of the Pointer, based on the current and previous positions. The velocity is smoothed out each frame according to the Pointer.motionFactor property. This is done for more accurate gesture recognition. The velocity is updated based on Pointer movement and doesn't require a button to be pressed first.
  • Pointer.angle is a new property that contains the angle of the Pointer, in radians, based on the current and previous positions. The angle is smoothed out each frame according to the Pointer.motionFactor property. This is done for more accurate gesture recognition. The angle is updated based on Pointer movement and doesn't require a button to be pressed first.
  • Pointer.distance is a new property that contains the distance of the Pointer, in radians, based on the current and previous positions. The distance is smoothed out each frame according to the Pointer.motionFactor property. This is done for more accurate gesture recognition. The distance is updated based on Pointer movement and doesn't require a button to be pressed first.
  • Pointer.motionFactor is a new property that controls how much smoothing to apply to the Pointer positions each frame. This value is passed to the Smooth Step Interpolation that is used to calculate the velocity, angle and distance of the Pointer. It's applied every frame until the midPoint reaches the current position of the Pointer. The default value is 0.2.
  • The Input Plugin was emitting a preUpdate event, with the capital U, instead of preupdate. This has now been corrected. Fix #4185 (thanks @gadelan)
  • Pointer.updateMotion is a new method that is called automatically, each step, by the Input Manager. It's responsible for calculating the Pointer velocity, angle and distance properties.
  • Pointer.time is a new property that holds the time the Pointer was last updated by the Game step.
  • Pointer.getDistance has been updated. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
  • Pointer.getDistanceX is a new method that will return the horizontal distance between the Pointer's previous and current coordinates. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
  • Pointer.getDistanceY is a new method that will return the horizontal distance between the Pointer's previous and current coordinates. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
  • Pointer.getDuration is a new method that will return the duration the Pointer was held down for. If the Pointer has a button pressed down at the time this method is called, it will return the duration since the Pointer's button was pressed down. If no button is held down, it will return the last recorded duration, based on the time the Pointer button was released.
  • Pointer.getAngle is a new method that will return the angle between the Pointer coordinates. 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.
  • In previous versions, the VisibilityHandler would create a mousedown listener for the game canvas and then call window.focus when detected (assuming the game config autoFocus property was true). Responsibility for this has now been moved to the Mouse Manager onMouseDown handler.
  • In previous versions, the VisibilityHandler would create a mouseout listener for the game canvas and then set game.isOver when detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input Manager isOver property directly.
  • In previous versions, the VisibilityHandler would create a mouseover listener for the game canvas and then set game.isOver when detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input Manager isOver property directly.
  • The Phaser.Game.isOver property has been moved. You can now find it in the Input Manager and it's also accessible via the Input Plugin, which means you can do this.input.isOver from within a Scene. This makes more sense as it's input related and not a game level property.
  • The Input Plugin has a new event you can listen to: gameover, which is triggered whenever the mouse or a pointer is moved over the Game canvas. Listen to it with this.input.on('gameover') from within a Scene.
  • The Input Plugin has a new event you can listen to: gameout, which is triggered whenever the mouse or a pointer leaves the Game canvas. Listen to it with this.input.on('gameout') from within a Scene.
  • The Game used to emit a mouseover event when the mouse entered the game canvas. This is no longer emitted by the Game itself and can instead be listened for using the new Input Plugin event gameover.
  • The Game used to emit a mouseout event when the mouse left the game canvas. This is no longer emitted by the Game itself and can instead be listened for using the new Input Plugin event gameout.
  • If the window object exists (which it will in normal browser environments) new mouseup and touchend event listeners are bound to it and trigger the normal mouseup or touchend events within the internal input system. This means you will now get a pointerup event from the Input Plugin even if the pointer is released outside of the game canvas. Pointers will also no longer think they are still 'down' if released outside the canvas and then moved inside again in their new state.
  • The window will now have focus called on it by the Touch Manager, as well as the Mouse Manager, if the autoFocus game config property is enabled.
  • The Input Plugin has a new event you can listen to: pointerdownoutside, which is triggered whenever the mouse or a pointer is pressed down while outside of the Game canvas. Listen to it with this.input.on('pointerdownoutside') from within a Scene.
  • The Input Plugin has a new event you can listen to: pointerupoutside, which is triggered whenever the mouse or a pointer is released while outside of the Game canvas. Listen to it with this.input.on('pointerupoutside') from within a Scene.
  • Pointer.downElement is a new property that holds the target of the DOM Event that triggered when the Pointer was pressed down. If this is within the game, this will be the game canvas element.
  • Pointer.upElement is a new property that holds the target of the DOM Event that triggered when the Pointer was released. If this is within the game, this will be the game canvas element.
  • The Pointer.dragState property has been removed. This is no longer used internally as it has to be tracked per Scene, not on a global level.
  • InputPlugin.setDragState is a new internal method that sets the drag state for the given Pointer.
  • InputPlugin.getDragState is a new internal method that gets the drag state for the given Pointer.
  • Draggable Game Objects would not work if you had multiple Scenes running in parallel, with draggable objects in both of them. Only the top-most Scene would work fully. Items in the bottom Scene would never finish their drag cycle, causing them to get stuck. Fix #4249 #4278 (thanks @probt @iArePJ)
  • Pointer.leftButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.rightButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.middleButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.backButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.forwardButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.up, Pointer.move and Pointer.down now use in to check for the existance of the buttons property on the event, causing it to be set even if equal to zero, which it is when there are no buttons down. This also fixes an issue where the buttons didn't update during a move event (thanks @SonnyCampbell @rexrainbow)

Changes as a result of the new Scale Manager

3.16 introduces the completed Scale Manager. This is fully documented, but the class, all methods and all properties. It also includes a folder full of examples in the Phaser Labs, so you're strongly recommended to start there.

  • If you set the Game Config property zoom to be > 1 then it will automatically enable pixelArt mode, unless you set pixelArt: false in the config.
  • There is a new property in the Game Config called autoRound, which controls if the canvas size and style sizes are passed through Math.floor or not. On some devices this can help with performance and anti-aliasing. The default is false (turned off).
  • The Game Config property autoResize has been removed as it's now redundant.
  • The WebGL and Canvas Renderers no longer change the Canvas size in their resize methods. They just update internal properties.
  • The WebGL and Canvas Renderers now read the width, height and resolution values from the Scale Manager, not the Game Config.
  • CameraManager.baseScale property has been removed as it's no longer used anywhere.
  • The BaseCamera and Camera preRender methods now only take a resolution argument and use it internally for their transforms.
  • InputManager.scaleManager is a new property that is a reference to the Scale Manager. This is populated in the boot method.
  • The InputManager.transformX method has been removed. This is now available in the ScaleManager.
  • The InputManager.transformY method has been removed. This is now available in the ScaleManager.
  • The InputManager.scale property has been removed. This is now available in the ScaleManager under displayScale.
  • The InputManager.resize method has been removed as this process is now handled by the ScaleManager.
  • The InputManager.bounds property has been removed as this process is now handled by the ScaleManager.
  • The InputManager.updateBounds method has been removed as this process is now handled by the ScaleManager.
  • The InputManager.getOffsetX method has been removed as it's no longer required.
  • The InputManager.getOffsetY method has been removed as it's no longer required.
  • The InputManager.getScaleX method has been removed as it's no longer required.
  • The InputManager.getScaleY method has been removed as it's no longer required.
  • The SceneManager.resize method has been removed as it's no longer required.
  • The Scene.Systems.resize method has been removed as it's no longer required.
  • Scenes will no longer dispatch the resize event. You should now listen for this event from the Scale Manager instead.
  • BaseCamera.config has been removed as it's no longer required.
  • BaseCamera.scaleManager is a new property that references the Scale Manager and is used internally for size checks.
  • The Game.resize method has been removed as it's no longer required. You should now call ScaleManager.resize instead.
  • The Game will no longer dispatch the resize event. You should now listen for this event from the Scale Manager instead.

Facebook Instant Games Updates and Fixes

  • Added the Leaderboard.getConnectedScores method, to get a list of scores from player connected entries.
  • The loadPlayerPhoto function in the Instant Games plugin now listens for the updated Loader event correctly, causing the photocomplete event to fire properly.
  • Leaderboard.setScore now emits the LeaderboardScore object with the setscore event, as the documentation said it did.
  • Leaderboard.getPlayerScore now only populates the playerScore property if the entry isn't null.
  • If the setScore or getPlayerScore calls fail, it will return null as the score instance, instead of causing a run-time error.
  • You can now pass an object or a string to setScore and objects will be automatically stringified.
  • The preloadAds method will now only create an AdInstance object if the interstitial loadSync promise resolves.
  • The preloadVideoAds method will now only create an AdInstance object if the interstitial loadSync promise resolves.
  • The preloadAds method will now emit the adsnofill event, if there are no ads in the inventory to load.
  • The preloadVideoAds method will now emit the adsnofill event, if there are no ads in the inventory to load.
  • The showAd method will now emit the adsnotloaded event, if there are no ads loaded matching the given Placement ID.
  • The showVideo method will now emit the adsnotloaded event, if there are no ads loaded matching the given Placement ID.
  • Showing an ad will emit the adfinished event when the ad is closed, previously this event was called showad but the new name better reflects what has happened.
  • The Facebook Plugin is now available in the Phaser.Scene class template under the facebook property (thanks @bryanwood)
  • Fixed the Leaderboard.getScores method to now take the arguments into account. Fix #4271 (thanks @Oramy)
  • Fixed an API validation error in the chooseContext method. Fix #4248 (thanks @yadurajiv)

New Features

  • You can now load external Scene files using the new load.sceneFile method. This allows you to dynamically load a Scene into the Scene Manager of your game, and swap to it at will. Please see the documentation and examples for further details.
  • The data object being sent to the Dynamic Bitmap Text callback now has a new property parent, which is a reference to the Bitmap Text instance that owns the data object (thanks ornyth)
  • The WebGL Renderer has a new method clearPipeline, which will clear down the current pipeline and reset the blend mode, ready for the context to be passed to a 3rd party library.
  • The WebGL Renderer has a new method rebindPipeline, which will rebind the given pipeline instance, reset the blank texture and reset the blend mode. This is useful for recovering from 3rd party libs that have modified the gl context.
  • Game Objects have a new property called state. Use this to track the state of a Game Object during its lifetime. For example, it could move from a state of 'moving', to 'attacking', to 'dead'. Phaser itself will never set this property, although plugins are allowed to.
  • Game Objects have a new method called setState which will set the state property in a chainable call.
  • BlendModes.ERASE is a new blend mode that will erase the object being drawn. When used in conjunction with a Render Texture it allows for effects that require you to erase parts of the texture, in either Canvas or WebGL. When used with a transparent game canvas, it allows you to erase parts of the canvas, showing the web page background through.
  • BlendModes.SOURCE_IN is a new Canvas-only blend mode that allows you to use the source-in composite operation when rendering Game Objects.
  • BlendModes.SOURCE_OUT is a new Canvas-only blend mode that allows you to use the source-out composite operation when rendering Game Objects.
  • BlendModes.SOURCE_ATOP is a new Canvas-only blend mode that allows you to use the source-atop composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_OVER is a new Canvas-only blend mode that allows you to use the destination-over composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_IN is a new Canvas-only blend mode that allows you to use the destination-in composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_OUT is a new Canvas-only blend mode that allows you to use the destination-out composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_ATOP is a new Canvas-only blend mode that allows you to use the destination-atop composite operation when rendering Game Objects.
  • BlendModes.LIGHTER is a new Canvas-only blend mode that allows you to use the lighter composite operation when rendering Game Objects.
  • BlendModes.COPY is a new Canvas-only blend mode that allows you to use the copy composite operation when rendering Game Objects.
  • BlendModes.XOR is a new Canvas-only blend mode that allows you to use the xor composite operation when rendering Game Objects.
  • RenderTexture.erase is a new method that will take an object, or array of objects, and draw them to the Render Texture using an ERASE blend mode, resulting in them being removed from the Render Texture. This is really handy for making a bitmap masked texture in Canvas or WebGL (without using an actual mask), or for 'cutting away' part of a texture.
  • There is a new boolean Game Config property called customEnvironment. If set to true it will skip the internal Feature checks when working out which type of renderer to create, allowing you to run Phaser under non-native web environments. If using this value, you must set an explicit renderType of either CANVAS or WEBGL. It cannot be left as AUTO. Fix #4166 (thanks @jcyuan)
  • Animation.nextFrame will advance an animation to the next frame in the sequence instantly, regardless of the animation time or state. You can call this on a Sprite: sprite.anims.nextFrame() (thanks rgk25)
  • Animation.previousFrame will set an animation to the previous frame in the sequence instantly, regardless of the animation time or state. You can call this on a Sprite: sprite.anims.previousFrame() (thanks rgk25)
  • Geom.Intersects.PointToLine has a new optional argument lineThickness (which defaults to 1). This allows you to determine if the point intersects a line of a given thickness, where the line-ends are circular (not square).
  • Geom.Line.GetNearestPoint is a new static method that will return the nearest point on a line to the given point.
  • Geom.Line.GetShortestDistance is a new static method that will return the shortest distance from a line to the given point.
  • Camera.getBounds is a new method that will return a rectangle containing the bounds of the camera.
  • Camera.centerOnX will move the camera horizontally to be centered on the given coordinate without changing its vertical placement.
  • Camera.centerOnY will move the camera vertically to be centered on the given coordinate without changing its horizontally placement.
  • AnimationManager.exists is a new method that will check to see if an Animation using the given key already exists or not and returns a boolean.
  • animationstart-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationstart-explode.
  • animationrestart-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationrestart-explode.
  • animationcomplete-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationcomplete-explode.
  • animationupdate-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationupdate-explode.
  • The Animation class now extends the Event Emitter and dispatches events itself. This allows you to listen for events from a specific Animation, rather than via a Game Object. This is handy, for example, if you had an explosion animation that you wanted to trigger a sound effect when it started. You can now listen for the events from the Animation object directly.
  • The Animation class now emits the start event when played (either forward, or in reverse) by any Game Object.
  • The Animation class now emits the restart event when it restarts playing on any Game Object.
  • The Animation class now emits the complete event when it finishes playing on any Game Object.
  • The Animation Component has a new method called chain which allows you to line-up another animation to start playing as soon as the current one stops, no matter how it stops (either by reaching its natural end, or directly by having stop called on it). 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 callback). 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.
  • CanvasTexture.drawFrame is a new method that allows you to draw a texture frame to the CanvasTexture based on the texture key and frame given.
  • CanvasTexture.getIndex is a new method that will take an x/y coordinate and return the Image Data index offset used to retrieve the pixel values.
  • CanvasTexture.getPixels is a new method that will take a region as an x/y and width/height and return all of the pixels in that region from the CanvasTexture.
  • CanvasTexture.setPixel is a new method that sets the given pixel in the CanvasTexture to the color and alpha values provided.
  • CanvasTexture.getData is a new method that will extract an ImageData block from the CanvasTexture from the region given.
  • CanvasTexture.putData is a new method that will put an ImageData block at the given coordinates in a CanvasTexture.
  • Line.Extend is a new static function that allows you extend the start and/or end points of a Line by the given amounts.
  • Vector2.LEFT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.RIGHT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.UP is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.DOWN is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.ONE is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.ZERO is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.LEFT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.RIGHT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.UP is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.DOWN is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.FORWARD is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.BACK is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.ONE is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Geometery Mask has a new property called invertAlpha in WebGL, which works in the same way as the flag on the Bitmap Mask and allows you to invert the function of the stencil buffer, i.e. non-drawn shapes become invisible, and drawn shapes visible (thanks @tfelix)
  • The Arcade Physics Body has a new property maxSpeed which limits the vector length of the Body velocity. You can set it via the method setMaxSpeed and it is applied in the World.computeVelocity method (thanks @Edwin222 @rexrainbow)
  • WebGLRenderer.snapshotArea is a new method that allows you to grab an image of the given region of the canvas during the post-render step and have it sent to your defined callback. This is the same as snapshot except you control the area being grabbed, so is more efficient if you only need a smaller area.
  • WebGLRenderer.snapshotPixel is a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as a Color object to your specified callback.
  • CanvasRenderer.snapshotArea is a new method that allows you to grab an image of the given region of the canvas during the post-render step and have it sent to your defined callback. This is the same as snapshot except you control the area being grabbed, so is more efficient if you only need a smaller area.
  • CanvasRenderer.snapshotPixel is a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as a Color object to your specified callback.
  • SceneManager.getScenes is a new method that will return all current Scenes being managed by the Scene Manager. You can optionally return only active scenes and reverse the order in which they are returned in the array.
  • DOM.GetTarget is a new helper function that will return a reference to a DOM Element based on the given string or node.
  • GameObjects.Extern is a new special type of Game Object that allows you to pass rendering off to a 3rd party. When you create an Extern and place it in the display list of a Scene, the renderer will process the list as usual. When it finds an Extern it will flush the current batch, clear down the pipeline and prepare a transform matrix which your render function can take advantage of, if required. The Extern Game Object is used heavily by the Spine Plugin, but can also be used by other libraries such as three.js, allowing them to render directly into a Phaser game.

Updates

  • You can now modify this.physics.world.debugGraphic.defaultStrokeWidth to set the stroke width of any debug drawn body, previously it was always 1 (thanks @samme)
  • TextStyle.setFont has a new optional argument updateText which will sets if the text should be automatically updated or not (thanks @DotTheGreat)
  • ProcessQueue.destroy now sets the internal toProcess counter to zero.
  • The PathFollower.pathRotationVerticalAdjust property has been removed. It was supposed to flipY a follower when it reversed path direction, but after some testing it appears it has never worked and it's easier to do this using events, so the property and associated config value are removed. The verticalAdjust argument from the setRotateToPath method has been removed as well.
  • The config value preserveDrawingBuffer has been removed as it has never been used by the WebGL Renderer.
  • PluginManager.install returns null if the plugin failed to install in all cases.
  • PluginFile will now install the plugin into the current Scene as long as the start or mapping arguments are provided.
  • MATH_CONST no longer requires or sets the Random Data Generator, this is now done in the Game Config, allowing you to require the math constants without pulling in a whole copy of the RNG with it.
  • The Dynamic Bitmap Text Canvas Renderer was creating a new data object every frame for the callback. It now uses the callbackData object instead, like the WebGL renderer does.
  • WebGLRenderer.setBlendMode has a new optional argument force, which will force the given blend mode to be set, regardless of the current settings.
  • The method DisplayList.sortGameObjects has been removed. It has thrown a runtime error since v3.3.0(!) which no-one even spotted which is a good indication of how little the method was used. The display list is automatically sorted anyway, so if you need to sort a small section of it, just use the standard JavaScript Array sort method (thanks ornyth)
  • The method DisplayList.getTopGameObject has been removed. It has thrown a runtime error since v3.3.0(!) which no-one even spotted which is a good indication of how little the method was used (thanks ornyth)
  • WebGLRenderer.setFramebuffer has a new optional boolean argument updateScissor, which will reset the scissor to match the framebuffer size, or clear it.
  • WebAudioSoundManager.onFocus will not try to resume the Audio Context if it's still locked.
  • WebAudioSoundManager.onBlur will not try to suspend the Audio Context if it's still locked.
  • When using ScenePlugin.add, to add a new Scene to the Scene Manager, it didn't allow you to include the optional Scene data object. You can now pass this in the call (thanks @kainage)
  • Graphics.stroke is a new alias for the strokePath method, to keep the calls consistent with the Canvas Rendering Context API.
  • Graphics.fill is a new alias for the fillPath method, to keep the calls consistent with the Canvas Rendering Context API.
  • LoaderPlugin.sceneManager is a new property that is a reference to the global Scene Manager, useful for Plugins.
  • Whenever Camera.roundPixels was enabled it would use a bitwise operation to truncate the float (x |= 0) - this has been replaced across all files that used it, with a call to Math.round instead. This gives far better results when zooming cameras both in and out of a Scene, stopping thin gaps appearing between closely packed Game Objects.
  • AnimationManager.create will now return a boolean false if the given key is invalid (i.e. undefined or falsey).
  • AnimationManager.create will no longer raise a console warning if the animation key is already in use. Instead, it will return the animation belonging to that key. A brand new animation will only be created if the key isn't already in use. When this happens, the add event is emitted by the Animation Manager. If no event is emitted, the animation already existed.
  • ArcadePhysics.Body.destroy will now only add itself to the World pendingDestroy list if the world property exists. This prevents Cannot read property 'pendingDestroy' of undefined errors if you try to delete a physics body in a callback and then immediately change Scene (which tells the physics work to also delete all bodies)
  • The Animation Component restart method has had is sole key argument removed. Previously, you had to pass in the key of the animation you wished to reverse, but now you can just call the method directly, and as long as there is an animation playing, it will automatically start playing in reverse, without the nee for a key (the way it should have been originally)
  • Animation.play and playReverse will now accept either a string-based key of the animation to play (like before), or you can pass in an Animation instance, and it will play that animation.
  • CanvasTexture.clear now has 4 new optional arguments: x, y, width, height which allow you to define the region of the texture to be cleared. If not provided it will clear the whole texture, which is the same behavior as before.
  • EarCut, the polygon triangulation library used by the Graphics and WebGL classes, has been upgraded from 2.1.1 to 2.1.4. 2.1.2 fixed a few race conditions where bad input would cause an error. 2.1.3 improved performance for bigger inputs (5-12%) and 2.1.4 fixed a race condition that could lead to a freeze on degenerate input.
  • TextureTintPipeline.batchQuad and batchTri have two new optional arguments texture and unit which are used to re-set the batch texture should the method cause a batch flush.
  • TextureTintPipeline.requireTextureBatch is a new internal method that helps speed-up the creation of texture batches. It is used in conjunction with setTexture2D and pushBatch.
  • TextureTintPipeline.flush and TextureTintPipeline.pushBatch have been optimized to handle zero based texture units as priority. They've also been refactored to avoid creation of empty texture batches.
  • The WebGLRenderer.setTexture2D method has a new optional argument flush which controls if the pipeline is flushed if the given texture is new, or not. This is used internally to skip flushing during an existing flush.
  • The Tilemap Layer width and height properties are now based on the tilemap tile sizes multiplied by the layer dimensions. This corrects an issue with layer sizes being wrong if you called setBaseTileSize on a Map.
  • The WebGLRenderer will now clear the framebuffer at the start of every render.
  • WebGLRenderer.setScissor now has a new optional argument drawingBufferHeight which allows you to specify the drawing buffer height, rather than use the renderers default value.
  • WebGLRenderer.pushScissor now has a new optional argument drawingBufferHeight which allows you to specify the drawing buffer height, rather than use the renderers default value.
  • WebGLRenderer.preRender now calls gl.clearColor in order to restore the background clear color in case something, like a Render Texture, has changed it.
  • Map.set will now update an existing value if you provide it with a key that already exists within the Map. Previously, if you tried to set the value of a key that existed it would be skipped.
  • MatterSprite would set its type property to be Image. It now sets it to be Sprite as it should do.
  • Matter.TileBody.setFromTileCollision no longer checks if the shape is concave or convex before modifying the vertices, as the update to the Matter.js lib in 3.12 stopped this from working with Tiled collision shapes.
  • The Scene transitionstart event is now dispatched by the Target Scene of a transition, regardless if the Scene has a create method or not. Previously, it was only dispatched if the Scene had a create method.
  • The Loader will now allow an XHR status of 0 as success too. Normally only status 200 would be accepted as success, but 0 is returned when a file is loaded from the local filesystem (file://). This happens, for example, when opening the index.html of a game in a browser directly, or when using Cordova on iOS. Fix #3464 (thanks @Ithamar)
  • Tween.restart now returns the Tween instance (thanks @rexrainbow)
  • Tween.play now returns the Tween instance (thanks @rexrainbow)
  • Tween.seek now returns the Tween instance (thanks @rexrainbow)
  • Tween.complete now returns the Tween instance (thanks @rexrainbow)
  • Tween.stop now returns the Tween instance (thanks @rexrainbow)
  • List.sort now has an optional parameter handler which allows you to provide your own sort handling function (thanks @jcyuan)
  • Container.sort now has an optional parameter handler which allows you to provide your own sort handling function (thanks @jcyuan)
  • The WebGLRenderer method canvasToTexture will now only set the filter to be NEAREST if antialias is disabled in the game config (i.e. when running in pixelArt mode). This means that Text objects, and other Canvas backed textures, now render with anti-aliasing if everything else does. You can disable this on a per-object basis by calling texture.setFilter(1) on them.
  • CanvasRenderer.snapshotCallback, snapshotType and snapshotEncoder have all been removed as they are no longer required.
  • CanvasRenderer.snapshotState is a new object that contains the snapshot configuration data, the same as the WebGL Renderer.
  • The signature of the WebGLSnapshot function has changed. It now takes a Snapshot Configuration object as the second parameter.
  • The signature of the CanvasSnapshot function has changed. It now takes a Snapshot Configuration object as the second parameter.
  • A Tween Timeline will now set it's internal destroy state before calling either the onComplete callback or sending the COMPLETE event. This means you can now call methods that will change the state of the Timeline, such as play, during the callback handlers, where-as before doing this would have had the internal state changed immediately, preventing it (thanks Lucas Knight)
  • The AddToDOM method has had the overflowHidden argument removed. The DOM element the canvas is inserted into no longer has overflow: hidden applied to its style. If you wish to have this, please add it directly via CSS.

Bug Fixes

  • The Rectangle Shape object wouldn't render if it didn't have a stroke, or any other objects on the display list (thanks mliko)
  • When using a font string instead of setting fontFamily, fontSize and fontStyle in either Text.setStyle or setFont, the style properties wouldn't get set. This isn't a problem while creating the text object, only if modifying it later (thanks @DotTheGreat)
  • Text.toJSON wasn't saving the font style when using the "font" shorthand to create it. It now saves it correctly. Fix #4141 (thanks @divillysausages)
  • Disabling camera bounds and then moving the camera to an area in a Tilemap that did not have any tile information would throw an Uncaught Reference error as it tried to access tiles that did not exist (thanks @Siyalatas)
  • Fixed an issue where Sprite Sheets being extracted from a texture atlas would fail if the sheet was either just a single column or single row of sprites. Fix #4096 (thanks @Cirras)
  • If you created an Arcade Physics Group without passing a configuration object, and passing an array of non-standard children, it would throw a classType runtime error. It now creates a default config object correctly (thanks @pierpo)
  • The Camera.cull method has been restructured so it now calculates if a Game Object is correctly in view or not before culling it. Although not used internally, if you need to cull objects for a camera, you can now safely use this method. Fix #4092 (thanks @Cirras)
  • The Tiled Parser would ignore animated tile data if it was in the new Tiled 1.2 format. This is now accounted for, as well as 1.0 (thanks @nkholski)
  • Array.Matrix.ReverseRows was actually reversing the columns, but now reverses the rows.
  • Array.Matrix.ReverseColumns was actually reversing the rows, but now reverses the columns.
  • UnityAtlas now sets the correct file type key if using a config file object.
  • Starting with version 3.13 in the Canvas Renderer, it was possible for long-running scripts to start to get bogged-down in fillRect calls if the game had a background color set. The context is now saved properly to avoid this. Fix #4056 (thanks @Aveyder)
  • Render Textures created larger than the size of the default canvas would be automatically clipped when drawn to in WebGL. They now reset the gl scissor and drawing height property in order to draw to their full size, regardless of the canvas size. Fix #4139 (thanks @chaoyang805 @iamchristopher)
  • The cameraFilter property of a Game Object will now allow full bitmasks to be set (a value of -1), instead of just those > 0 (thanks @stuartkeith)
  • The PathFollower.startFollow method now properly uses the startAt argument to the method, so you can start a follower off at any point along the path. Fix #3688 (thanks @DannyT @diteix)
  • Static Circular Arcade Physics Bodies now render as circles in the debug display instead of showing their rectangle bounds (thanks @maikthomas)
  • Changing the mute flag on an HTML5AudioSound instance, via the mute setter, now works as it does via the Sound Manager (thanks @Waclaw-I @neon-dev)
  • Changing the volume on an HTML5AudioSound instance, via the volume setter, now works as it does via the Sound Manager (thanks @Waclaw-I)
  • The Dynamic Tilemap Layer WebGL renderer was drawing tiles at the incorrect position if the layer was scaled. Fix #4104 (thanks @the-realest-stu)
  • Tile.tileset now returns the specific Tileset associated with the tile rather than an array of them. Fix #4095 (thanks @quadrupleslap)
  • Tile.getCollisionGroup wouldn't return the correct Group after the change to support multiple Tilesets. It now returns the group properly (thanks @jbpuryear)
  • Tile.getTileData wouldn't return the correct data after the change to support multiple Tilesets. It now returns the tile data properly (thanks @jbpuryear)
  • The GetTileAt and RemoveTileAt components would error with "Cannot read property 'index' of undefined" if the tile was undefined rather than null. It now handles both cases (thanks @WaSa42)
  • Changing TileSprite.width or TileSprite.height will now flag the texture as dirty and call updateDisplayOrigin, allowing you to resize TileSprites dynamically in both Canvas and WebGL.
  • RandomDataGenerator.shuffle has been fixed to use the proper modifier in the calculation allowing for a more even distribution (thanks wayfinder)
  • The Particle Emitter was not recycling dead particles correctly so it was creating new objects every time it emitted (the old particles were then left to the browsers gc to clear up). This has now been recoded so the emitter will properly keep track of dead particles and re-use them (thanks @Waclaw-I for the initial PR)
  • ParticleEmitter.indexSortCallback has been removed as it's no longer required.
  • Particle.index has been removed as it's no longer required. Particles don't need to keep track of their index any more.
  • The Particle Emitter no longer needs to call the StableSort.inplace during its preUpdate, saving cpu.
  • Particle.resetPosition is a new method that is called when a particle dies preparing it for firing again in the future.
  • The Canvas SetTransform method would save the context state, but it wasn't restored at the end in the following Game Objects: Dynamic Bitmap Text, Graphics, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. These now all restore the context, meaning if you're using non-canvas sized cameras in Canvas mode, it will now render beyond just the first custom camera.
  • Utils.Array.MoveUp wouldn't let you move an array element to the top-most index in the array. This also impacted Container.moveUp.
  • The Texture Tint Pipeline had a logic error that would cause every 2001st quad to either be invisible, or pick-up the texture of the 2000th quad by mistake. The batchQuad and batchTri methods how handle re-assigning the batch texture if they cause a batch flush as part of their process.
  • Rotating Sprites that used a Normal Map wouldn't rotate the normal map with it causing the lighting effects to become irregular. The normal map vectors are now rotated correctly (thanks @sercant for the PR and @fazzamatazz and @ysraelJMM for the report)
  • Changing scaleX or scaleY on a MatterImage or MatterSprite would cause the body scale to become distorted as the setters didn't use the correct factor when resetting the initial scale. Fix #4206 (thanks @YannCaron)
  • StaticBody.reset in Arcade Physics would ignore the x and y values given to it. If given, they're now used to reset the parent Game Object before the body is updated. Fix #4224 (thanks @samme)
  • Static Tilemap Layers wouldn't render correctly if the layer used a tileset with a different size to the base map data (set via setBaseTileSize). They now render correctly in WebGL and Canvas regardless of the base tile size.
  • When using RenderTexture.fill, the alpha argument would be ignored in Canvas mode. It's now used when filling the RenderTexture.
  • Fixed an issue in WebGLRenderer.setScissor where it was possible to try and compare the scissor size to a non-current scissor if called outside of the render loop (i.e. from RenderTexture.fill) (thanks @hackhat)
  • RenderTexture.fill in WebGL would use gl.clear and a clear color to try and fill the Render Texture. This only worked for full-canvas sized RenderTextures that didn't have a camera zoom applied. It has now been swapped to use the drawFillRect method of the Texture Tint Pipeline, allowing it to work properly regardless of camera zoom or size.
  • Container.getFirst was using an incorrect Array Utils function GetFirstElement when it should have been using GetFirst. It now uses the correct function. Fix #4244 (thanks @miran248)
  • List.getFirst was using an incorrect Array Utils function GetFirstElement when it should have been using GetFirst. It now uses the correct function. Fix #4244 (thanks @miran248)
  • Fixed an issue where changing the viewport or size of a Camera belonging to a RenderTexture wouldn't impact the rendering and objects will still render outside of the viewport range. It's now converted to a proper gl scissor rect by the renderer, meaning you can limit the area rendered to by adjusting the internal Render Texture cameras viewport. Fix #4243 (thanks @hackhat)
  • CanvasTexture.destroy is a new method that specifically handles the destruction of the CanvasTexture and all of its associated typed arrays. This prevents a memory leak when creating and destroying lots of RenderTextures (which are CanvasTexture backed). Fix #4239 (thanks @sjb933)
  • The Alpha, Flip and Origin components have been removed from the Mesh Game Object (and by extension, Quad as well) as they are not used in the renderer and should be manipulated via the Mesh properties. Fix #4188 (thanks @enriqueto)
  • The processDomCallbacks method in the Input Manager wasn't correctly clearing the once arrays. Responsibility for this has now been passed to the queue methods queueTouchStart, queueTouchMove, queueTouchEnd, queueMouseDown, queueMouseMove and queueMouseUp. Fix #4257 (thanks @iArePJ)
  • Arcade Physics now manages when postUpdate should be applied better, stopping it from gaining a zero delta during a further check in the same frame. This fixes various issues, including the mass collision test demo. Fix #4154 (thanks @samme)
  • Arcade Physics could trigger a collide event on a Body even if it performing an overlap check, if the onCollide property was true (thanks @samme)
  • TileSprites no longer cause a crash when using the Headless mode renderer. Fix #4297 (thanks @clesquir)
  • The WebGLRenderer will now apply a transparent background if transparent = true in the game config (thanks @gomachan7)
  • List.sort was missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)
  • Container.sort was missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)
  • DataManager.pop would emit the DataManager instance, instead of the parent, as the first event argument. It now emits the parent as it should do. Fix #4186 (thanks @gadelan)
  • The GetValue function wasn't checking for the existance of '.' in the config property name correctly, causing the branch to always be taken (thanks @kyranet)
  • Safari had permission problems playing HTML5 Audio files on Mac OS. Due to the changes in the input event system audio now plays properly based on user interactions. You still can't play it automatically, though, it will always require a user gesture to begin. Fix #4217 (thanks @increpare)

Examples and TypeScript

Thanks to the following for helping with the Phaser 3 Examples and TypeScript definitions, either by reporting errors, or even better, fixing them:

@guilhermehto @samvieten @darkwebdev @RoryO @snowbillr @slothyrulez @jcyuan @jestarray @CzBiX

Phaser Doc Jam

The Phaser Doc Jam was a community-backed effort to try and get the Phaser 3 API documentation to 100% coverage. The Doc Jam is now over and I offer my thanks to the following who helped with docs in this release:

@16patsle - @gurungrahul2 - @icbat - @samme - @telinc1 - anandu pavanan - blackhawx - candelibas - Diego Romero - doronlinder - Elliott Wallace - eric - Georges Gabereau - Haobo Zhang - henriacle - jak6jak - Jake Jensen - James Van Roose - JamesSkemp - joelahoover - Joey - madclaws - marc136 - Mihail Ilinov - naum303 - NicolasRoehm - nuane - rejacobson - Robert Kowalski - rodri042 - rootasjey - sawamara - scottwestover - sir13tommy - stetso - therealsamf - Tigran - willblackmore - zenwaichi

Also, the following helped with the docs outside of the Doc Jam:

@bryanwood @jestarray @matosummer @tfelix @imilo @BigZaphod @OmarShehata @16patsle @jcyuan @iam13islucky @FractalBobz Endre

- JavaScript
Published by photonstorm over 7 years ago

phaser - Phaser v3.16.0

Phaser 3.16 is a massive update. The single largest in the history of Phaser 3 and it contains breaking changes. If you're upgrading from an earlier version please do check the log entries below.

Important Namespace Changes

  • The Phaser.Boot namespace has been renamed to Phaser.Core. As a result, the boot folder has been renamed to core. This impacts the TimeStep class and VisibilityHandler function, which have been moved to be under the new namespace.
  • The Phaser.Animations namespace was incorrectly exposed in the Phaser entrypoints as Animation (note the lack of plural). This means that if you are creating any custom classes that extend Animation objects using the Phaser namespace, then please update them from Phaser.Animation to Phaser.Animations, i.e. Phaser.Animation.AnimationFrame to Phaser.Animations.AnimationFrame. This doesn't impact you if you created animations directly via the Animation Manager.
  • The keyed Data Manager change data event string has changed from changedata_ to changedata- to keep it consistent with other keyed events. Note the change from _ to -.
  • The Keyboard Plugin keydown dynamic event string has changed from keydown_ to keydown- to keep it consistent with other keyed events. Note the change from _ to -.
  • The Keyboard Plugin keyup dynamic event string has changed from keyup_ to keyup- to keep it consistent with other keyed events. Note the change from _ to -.
  • The texturesready event emitted by the Texture Manager has been renamed to ready.
  • The loadcomplete event emitted by the Loader Plugin has been renamed to postprocess to be reflect what it's used for.
  • Game Objects used to emit a collide event if they had an Arcade Physics Body with onCollide set, that collided with a Tile. This has changed. The event has been renamed to tilecollide and you should now listen for this event from the Arcade Physics World itself: this.physics.world.on('tilecollide'). Game Objects no longer emit this event.
  • Game Objects used to emit an overlap event if they had an Arcade Physics Body with onOverlap set, that overlapped with a Tile. This has changed. The event has been renamed to tileoverlap and you should now listen for this event from the Arcade Physics World itself: this.physics.world.on('tileoverlap'). Game Objects no longer emit this event.
  • The function Phaser.Physics.Impact.SeperateX has been renamed to SeparateX to correct the spelling mistake.
  • The function Phaser.Physics.Impact.SeperateY has been renamed to SeparateY to correct the spelling mistake.
  • The ended event in WebAudioSound has been renamed to complete to make it more consistent with the rest of the API.
  • The ended event in HTML5AudioSound has been renamed to complete to make it more consistent with the rest of the API.
  • The Phaser.Utils.Objects namespace was incorrectly exposed in the Phaser entrypoints as Object (note the lack of plural), this has now been fixed so all associated functions are properly namespaced.
  • Phaser.GameObjects.Blitter.Bob has been renamed to Phaser.GameObjects.Bob to avoid namespace conflicts in TypeScript.
  • Phaser.GameObjects.Text.TextStyle has been renamed to Phaser.GameObjects.TextStyle to avoid namespace conflicts in TypeScript.

Important Changes to the Input System

In Phaser 3.15 and earlier the Input system worked using an event queue. All native DOM input events, such as from the Mouse, Touch or Keyboard, were picked up by event handlers and stored in a queue within the Input Manager. This queue was then processed during the next game step, all the events were dealt with and then it was cleared, ready to receive more events. As they were processed, the internal Phaser events such as pointerdown or keyup were dispatched to your game code.

This worked fine in that you were able to guarantee exactly when the events would arrive, because it was always at the same time in the game step. However, it had the side effect of you not being able to do things like open external browser windows, or go into Full Screen mode, during your event handlers - because they weren't "real" events, so didn't pass the browser security checks. To this end, methods like addUpCallback were added to try and provide this support (although it was never possible for keyboard events).

In 3.16 this has changed. The DOM Events now trigger the respective internal events immediately, in the same invocation. So if you click on the canvas, the pointerdown event you receive in your game is still part of the 'native' event handler, so you're now free to do things like go into full screen mode, or open external windows, without any browser warnings or work-arounds.

It does, however, mean that the point at which these handlers are called is no longer always consistent, and is no longer bound to the speed of the Request Animation Frame update. We've tested as much as possible, and so far, things carry on working as before. We've noticed a slight increase in responsiveness, due to the removal of the fractional delay in processing the events, which feels good. However, if for whatever reason this change has broken your game then you're able to easily switch back to the previous version. In your Game Config, create an input object and give it the property queue: true. This will tell Phaser to use the legacy event queue system.

Please note that we will remove this legacy system in the near future. So, please try and adapt your games to use the new system. If you've found an edge-case where something breaks because of it, please report it so we can look into it.

As a result of this change, the following are now deprecated:

  • InputPlugin.addUpCallback method.
  • InputPlugin.addDownCallback method.
  • InputPlugin.addMoveCallback method.
  • InputManager.queue property.
  • InputManager.domCallbacks property.
  • InputManager._hasUpCallback property.
  • InputManager._hasDownCallback property.
  • InputManager._hasMoveCallback property.
  • InputManager.processDomCallbacks method.
  • InputManager.addUpCallback method.
  • InputManager.addDownCallback method.
  • InputManager.addMoveCallback method.

keydown and keyup changes

Due to unification across the event system, the keydown_ and keyup_ dynamic event strings have changed.

  • In all cases the keydown_KEY event name has changed to keydown-KEY. Note the change from an underscore to a hyphen.
  • In all cases the keyup_KEY event name has changed to keyup-KEY. Note the change from an underscore to a hyphen.

You should update your game code accordingly.

Keyboard Input - New Features

The specificity of the Keyboard events has been changed to allow you more control over event handling. Previously, the Keyboard Plugin would emit the global keydown-CODE event first (where CODE was a keycode string, like keydown-A), then it would emit the global keydown event. In previous versions, Key objects, created via this.input.keyboard.addKey(), didn't emit events.

The Key class now extends EventEmitter and emits two new events directly: down and up. This means you can listen for an event from a Key you've created, i.e.: yourKey.on('up', handler).

The order has also now changed. If it exists, the Key object will dispatch its down event first. Then the Keyboard Plugin will dispatch keydown_CODE and finally the least specific of them all, keydown will be dispatched.

You also now have the ability to cancel this at any stage either on a local or global level. All event handlers are sent an event object which you can call event.stopImmediatePropagation() on. This will immediately stop any further listeners from being invoked in the current Scene. Therefore, if you call stopImmediatePropagation() in the Key.on handler, then the Keyboard Plugin will not emit either the keydown-CODE or keydown global events. You can also call stopImmediatePropagation() during the keydown-CODE handler, to stop it reaching the global keydown handler. As keydown is last, calling it there has no effect.

There is also the stopPropagation() function. This works in the same way as stopImmediatePropagation but instead of being local, it works across all of the Scenes in your game. For example, if you had 3 active Scenes (A, B and C, with A at the top of the Scene list), all listening for the same key, calling stopPropagation() in Scene A would stop the event from reaching any handlers in Scenes B or C. Remember that events flow down the Scene list from top to bottom. So, the top-most rendering Scene in the Scene list has priority over any Scene below it.

All the above also works for keyup events.

New in 3.16 is the ability to receive a global keydown or keyup event from any key on the keyboard. Previously, it would only emit the event if it came from one of the keys listed in the KeyCodes file. Now, those global events will fire for any key, regardless of location.

Keyboard Captures

Key capturing is the way in which you stop a keyboard DOM event from activating anything else in the browser by calling preventDefault on it. For example, in tall web pages, pressing the SPACE BAR causes the page to scroll down. Obviously, if this is also the fire or jump button in your game, you don't want this to happen. So the key needs to be 'captured' to prevent it. Equally, you may wish to also capture the arrow keys, for similar reasons. Key capturing is done on a global level. If you set-up the capture of a key in one Scene, it will be captured globally across the whole game.

In 3.16 you now do this using the new KeyboardPlugin.addCapture method. This takes keycodes as its argument. You can either pass in a single key code (i.e. 32 for the Space Bar), an array of key codes, or a comma-delimited string - in which case the string is parsed and each code it can work out is captured.

To remove a capture you can use the KeyboardPlugin.removeCapture method, which takes the same style arguments as adding captures. To clear all captures call KeyboardPlugin.clearCaptures. Again, remember that these actions are global.

You can also temporarily enable and disable capturing using KeyboardPlugin.enableGlobalCapture and KeyboardPlugin.disableGlobalCapture. This means if you set-up a bunch of key captures, but then need to disable them all for a while (perhaps you swap focus to a DOM text field), you can call disableGlobalCapture to do this, and when finished in the DOM you can enable captures again with enableGlobalCapture, without having to clear and re-create them all.

Default captures can be defined in the Game Config in the input.keyboard.captures object. The captures are actually stored in the KeyboardManager class. The KeyboardPlugin is just a proxy to methods in the Keyboard Manager, but is how you should interface with it.

  • KeyboardPlugin.addCapture is a new method that allows you to define a set of keycodes to have the default browser behaviors disabled on.
  • KeyboardPlugin.removeCapture is a new method that removes specific previously set key captures.
  • KeyboardPlugin.clearCaptures is a new method that removes all key captures.
  • KeyboardPlugin.getCaptures is a new method that returns an array of all current key captures.
  • KeyboardPlugin.enableGlobalCapture is a new method that enables any key captures that have been created.
  • KeyboardPlugin.disableGlobalCapture is a new method that disables any key captures that have been created, without removing them from the captures list.
  • KeyboardPlugin.addKey has a new boolean argument enableCapture, which is true by default, that will add a key capture for the Key being created.
  • KeyboardPlugin.addKeys has a new boolean argument enableCapture, which is true by default, that will add a key capture for any Key created by the method.

Other Keyboard Updates and Fixes

  • There is a new class called KeyboardManager. This class is created by the global Input Manager if keyboard access has been enabled in the Game config. It's responsible for handling all browser keyboard events. Previously, the KeyboardPlugin did this which meant that every Scene that had its own Keyboard Plugin was binding more native keyboard events. This was causing problems with parallel Scenes when needing to capture keys. the KeyboardPlugin class still exists, and is still the main point of interface when you call this.input.keyboard in a Scene, but DOM event handling responsibility has been taken away from it. This means there's now only one set of bindings ever created, which makes things a lot cleaner.
  • There is a new Game and Scene Config setting input.keyboard.capture which is an array of KeyCodes that the Keyboard Plugin will capture all non-modified key events on. By default it is empty. You can populate it in the config, or use the new capture methods.
  • The Keyboard Manager will now call preventDefault only on non-modified key presses, stopping the keyboard event from hitting the browser. Previously, capturing the R key, for example, would block a CTRL+R page reload, but it now ignores it because of the key modifier.
  • If the browser Window loses focus, either from switching to another app, or another tab, all active Keys will be reset. This prevents issues with keys still reporting as being held down after leaving the game and returning to it again. Fix #4134 (thanks @Simplonium)
  • Key.emitOnRepeat is a new boolean property that controls if the 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).
  • Key.setEmitOnRepeat is a new chainable method for setting the emitOnRepeat property.
  • The KeyboardPlugin.addKeys method has a new optional boolean emitOnRepeat which sets that property on all Key objects it creates as part of the call. It defaults to false.
  • The KeyboardPlugin.addKey method has a new optional boolean emitOnRepeat which sets that property on the Key object it creates. It defaults to false.
  • The Key class now extends EventEmitter and emits two events directly: down and up. This means you can listen for an event from a Key you've created, i.e.: yourKey.on('up', handler).
  • The following Key Codes have been added, which include some missing alphabet letters in Persian and Arabic: SEMICOLON_FIREFOX, COLON, COMMA_FIREFOX_WINDOWS, COMMA_FIREFOX, BRACKET_RIGHT_FIREFOX and BRACKET_LEFT_FIREFOX (thanks @wmateam)
  • Key.onDown is a new method that handles the Key being pressed down, including down repeats.
  • Key.onUp is a new method that handles the Key being released.
  • Key.destroy is a new method that handles Key instance destruction. It is called automatically in KeyboardPlugin.destroy.
  • The Key.preventDefault property has been removed. This is now handled by the global keyboard capture methods.
  • Key.metaKey is a new boolean property which indicates if the Meta Key was held down when the Key was pressed. On a Mac the Meta Key is Command. On a Windows keyboard, it's the Windows key.
  • InputManager.keyboard is a new property that instantiates the global Keyboard Manager, if enabled in the game config.
  • The KeyboardPlugin.addKey method has a new boolean property enableCapture which automatically prevents default on the Key being created.
  • The KeyboardPlugin.addKeys method has a new boolean property enableCapture which automatically prevents default on Keys being created.
  • Phaser.Input.Keyboard.ProcessKeyDown has been removed as it's no longer required, Key.onDown handles it instead.
  • Phaser.Input.Keyboard.ProcessKeyUp has been removed as it's no longer required, Key.onUp handles it instead.
  • The Keyboard Manager has a property called captures which is an array of keycodes, as populated by the Game Config. Any key code in the array will have preventDefault called on it if pressed.
  • KeyboardPlugin.manager is a new property that references the Keyboard Manager and is used internally.
  • KeyboardPlugin.target has been removed as it's no longer used by the class.
  • KeyboardPlugin.queue has been removed as it's no longer used by the class.
  • KeyboardPlugin.onKeyHandler has been removed as it's no longer used by the class.
  • KeyboardPlugin.startListeners has been removed as it's no longer used by the class.
  • KeyboardPlugin.stopListeners has been removed as it's no longer used by the class.

Mouse and Touch Input - New Features, Updates and Fixes

  • The Mouse Manager class has been updated to remove some commented out code and refine the startListeners method.
  • When enabling a Game Object for input it will now use the width and height properties of the Game Object first, falling back to the frame size if not found. This stops a bug when enabling BitmapText objects for input and it using the font texture as the hit area size, rather than the text itself.
  • Pointer.smoothFactor is a float-value that allows you to automatically apply smoothing to the Pointer position as it moves. This is ideal when you want something smoothly tracking a pointer in a game, or are need a smooth drawing motion for an art package. The default value is zero, meaning disabled. Set to a small number, such as 0.2, to enable.
  • Config.inputSmoothFactor is a new property that allows you to set the smoothing factor for all Pointers the game creates. The default value is zero, which is disabled. Set in the game config as input: { smoothFactor: value }.
  • InputManager.transformPointer has a new boolean argument wasMove, which controls if the pointer is being transformed after a move or up/down event.
  • Pointer.velocity is a new Vector2 that contains the velocity of the Pointer, based on the current and previous positions. The velocity is smoothed out each frame according to the Pointer.motionFactor property. This is done for more accurate gesture recognition. The velocity is updated based on Pointer movement and doesn't require a button to be pressed first.
  • Pointer.angle is a new property that contains the angle of the Pointer, in radians, based on the current and previous positions. The angle is smoothed out each frame according to the Pointer.motionFactor property. This is done for more accurate gesture recognition. The angle is updated based on Pointer movement and doesn't require a button to be pressed first.
  • Pointer.distance is a new property that contains the distance of the Pointer, in radians, based on the current and previous positions. The distance is smoothed out each frame according to the Pointer.motionFactor property. This is done for more accurate gesture recognition. The distance is updated based on Pointer movement and doesn't require a button to be pressed first.
  • Pointer.motionFactor is a new property that controls how much smoothing to apply to the Pointer positions each frame. This value is passed to the Smooth Step Interpolation that is used to calculate the velocity, angle and distance of the Pointer. It's applied every frame until the midPoint reaches the current position of the Pointer. The default value is 0.2.
  • The Input Plugin was emitting a preUpdate event, with the capital U, instead of preupdate. This has now been corrected. Fix #4185 (thanks @gadelan)
  • Pointer.updateMotion is a new method that is called automatically, each step, by the Input Manager. It's responsible for calculating the Pointer velocity, angle and distance properties.
  • Pointer.time is a new property that holds the time the Pointer was last updated by the Game step.
  • Pointer.getDistance has been updated. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
  • Pointer.getDistanceX is a new method that will return the horizontal distance between the Pointer's previous and current coordinates. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
  • Pointer.getDistanceY is a new method that will return the horizontal distance between the Pointer's previous and current coordinates. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
  • Pointer.getDuration is a new method that will return the duration the Pointer was held down for. If the Pointer has a button pressed down at the time this method is called, it will return the duration since the Pointer's button was pressed down. If no button is held down, it will return the last recorded duration, based on the time the Pointer button was released.
  • Pointer.getAngle is a new method that will return the angle between the Pointer coordinates. 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.
  • In previous versions, the VisibilityHandler would create a mousedown listener for the game canvas and then call window.focus when detected (assuming the game config autoFocus property was true). Responsibility for this has now been moved to the Mouse Manager onMouseDown handler.
  • In previous versions, the VisibilityHandler would create a mouseout listener for the game canvas and then set game.isOver when detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input Manager isOver property directly.
  • In previous versions, the VisibilityHandler would create a mouseover listener for the game canvas and then set game.isOver when detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input Manager isOver property directly.
  • The Phaser.Game.isOver property has been moved. You can now find it in the Input Manager and it's also accessible via the Input Plugin, which means you can do this.input.isOver from within a Scene. This makes more sense as it's input related and not a game level property.
  • The Input Plugin has a new event you can listen to: gameover, which is triggered whenever the mouse or a pointer is moved over the Game canvas. Listen to it with this.input.on('gameover') from within a Scene.
  • The Input Plugin has a new event you can listen to: gameout, which is triggered whenever the mouse or a pointer leaves the Game canvas. Listen to it with this.input.on('gameout') from within a Scene.
  • The Game used to emit a mouseover event when the mouse entered the game canvas. This is no longer emitted by the Game itself and can instead be listened for using the new Input Plugin event gameover.
  • The Game used to emit a mouseout event when the mouse left the game canvas. This is no longer emitted by the Game itself and can instead be listened for using the new Input Plugin event gameout.
  • If the window object exists (which it will in normal browser environments) new mouseup and touchend event listeners are bound to it and trigger the normal mouseup or touchend events within the internal input system. This means you will now get a pointerup event from the Input Plugin even if the pointer is released outside of the game canvas. Pointers will also no longer think they are still 'down' if released outside the canvas and then moved inside again in their new state.
  • The window will now have focus called on it by the Touch Manager, as well as the Mouse Manager, if the autoFocus game config property is enabled.
  • The Input Plugin has a new event you can listen to: pointerdownoutside, which is triggered whenever the mouse or a pointer is pressed down while outside of the Game canvas. Listen to it with this.input.on('pointerdownoutside') from within a Scene.
  • The Input Plugin has a new event you can listen to: pointerupoutside, which is triggered whenever the mouse or a pointer is released while outside of the Game canvas. Listen to it with this.input.on('pointerupoutside') from within a Scene.
  • Pointer.downElement is a new property that holds the target of the DOM Event that triggered when the Pointer was pressed down. If this is within the game, this will be the game canvas element.
  • Pointer.upElement is a new property that holds the target of the DOM Event that triggered when the Pointer was released. If this is within the game, this will be the game canvas element.
  • The Pointer.dragState property has been removed. This is no longer used internally as it has to be tracked per Scene, not on a global level.
  • InputPlugin.setDragState is a new internal method that sets the drag state for the given Pointer.
  • InputPlugin.getDragState is a new internal method that gets the drag state for the given Pointer.
  • Draggable Game Objects would not work if you had multiple Scenes running in parallel, with draggable objects in both of them. Only the top-most Scene would work fully. Items in the bottom Scene would never finish their drag cycle, causing them to get stuck. Fix #4249 #4278 (thanks @probt @iArePJ)
  • Pointer.leftButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.rightButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.middleButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.backButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.forwardButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.up, Pointer.move and Pointer.down now use in to check for the existance of the buttons property on the event, causing it to be set even if equal to zero, which it is when there are no buttons down. This also fixes an issue where the buttons didn't update during a move event (thanks @SonnyCampbell @rexrainbow)

Changes as a result of the new Scale Manager

3.16 introduces the completed Scale Manager. This is fully documented, but the class, all methods and all properties. It also includes a folder full of examples in the Phaser Labs, so you're strongly recommended to start there.

  • If you set the Game Config property zoom to be > 1 then it will automatically enable pixelArt mode, unless you set pixelArt: false in the config.
  • There is a new property in the Game Config called autoRound, which controls if the canvas size and style sizes are passed through Math.floor or not. On some devices this can help with performance and anti-aliasing. The default is false (turned off).
  • The Game Config property autoResize has been removed as it's now redundant.
  • The WebGL and Canvas Renderers no longer change the Canvas size in their resize methods. They just update internal properties.
  • The WebGL and Canvas Renderers now read the width, height and resolution values from the Scale Manager, not the Game Config.
  • CameraManager.baseScale property has been removed as it's no longer used anywhere.
  • The BaseCamera and Camera preRender methods now only take a resolution argument and use it internally for their transforms.
  • InputManager.scaleManager is a new property that is a reference to the Scale Manager. This is populated in the boot method.
  • The InputManager.transformX method has been removed. This is now available in the ScaleManager.
  • The InputManager.transformY method has been removed. This is now available in the ScaleManager.
  • The InputManager.scale property has been removed. This is now available in the ScaleManager under displayScale.
  • The InputManager.resize method has been removed as this process is now handled by the ScaleManager.
  • The InputManager.bounds property has been removed as this process is now handled by the ScaleManager.
  • The InputManager.updateBounds method has been removed as this process is now handled by the ScaleManager.
  • The InputManager.getOffsetX method has been removed as it's no longer required.
  • The InputManager.getOffsetY method has been removed as it's no longer required.
  • The InputManager.getScaleX method has been removed as it's no longer required.
  • The InputManager.getScaleY method has been removed as it's no longer required.
  • The SceneManager.resize method has been removed as it's no longer required.
  • The Scene.Systems.resize method has been removed as it's no longer required.
  • Scenes will no longer dispatch the resize event. You should now listen for this event from the Scale Manager instead.
  • BaseCamera.config has been removed as it's no longer required.
  • BaseCamera.scaleManager is a new property that references the Scale Manager and is used internally for size checks.
  • The Game.resize method has been removed as it's no longer required. You should now call ScaleManager.resize instead.
  • The Game will no longer dispatch the resize event. You should now listen for this event from the Scale Manager instead.

Facebook Instant Games Updates and Fixes

  • Added the Leaderboard.getConnectedScores method, to get a list of scores from player connected entries.
  • The loadPlayerPhoto function in the Instant Games plugin now listens for the updated Loader event correctly, causing the photocomplete event to fire properly.
  • Leaderboard.setScore now emits the LeaderboardScore object with the setscore event, as the documentation said it did.
  • Leaderboard.getPlayerScore now only populates the playerScore property if the entry isn't null.
  • If the setScore or getPlayerScore calls fail, it will return null as the score instance, instead of causing a run-time error.
  • You can now pass an object or a string to setScore and objects will be automatically stringified.
  • The preloadAds method will now only create an AdInstance object if the interstitial loadSync promise resolves.
  • The preloadVideoAds method will now only create an AdInstance object if the interstitial loadSync promise resolves.
  • The preloadAds method will now emit the adsnofill event, if there are no ads in the inventory to load.
  • The preloadVideoAds method will now emit the adsnofill event, if there are no ads in the inventory to load.
  • The showAd method will now emit the adsnotloaded event, if there are no ads loaded matching the given Placement ID.
  • The showVideo method will now emit the adsnotloaded event, if there are no ads loaded matching the given Placement ID.
  • Showing an ad will emit the adfinished event when the ad is closed, previously this event was called showad but the new name better reflects what has happened.
  • The Facebook Plugin is now available in the Phaser.Scene class template under the facebook property (thanks @bryanwood)
  • Fixed the Leaderboard.getScores method to now take the arguments into account. Fix #4271 (thanks @Oramy)
  • Fixed an API validation error in the chooseContext method. Fix #4248 (thanks @yadurajiv)

New Features

  • You can now load external Scene files using the new load.sceneFile method. This allows you to dynamically load a Scene into the Scene Manager of your game, and swap to it at will. Please see the documentation and examples for further details.
  • The data object being sent to the Dynamic Bitmap Text callback now has a new property parent, which is a reference to the Bitmap Text instance that owns the data object (thanks ornyth)
  • The WebGL Renderer has a new method clearPipeline, which will clear down the current pipeline and reset the blend mode, ready for the context to be passed to a 3rd party library.
  • The WebGL Renderer has a new method rebindPipeline, which will rebind the given pipeline instance, reset the blank texture and reset the blend mode. This is useful for recovering from 3rd party libs that have modified the gl context.
  • Game Objects have a new property called state. Use this to track the state of a Game Object during its lifetime. For example, it could move from a state of 'moving', to 'attacking', to 'dead'. Phaser itself will never set this property, although plugins are allowed to.
  • Game Objects have a new method called setState which will set the state property in a chainable call.
  • BlendModes.ERASE is a new blend mode that will erase the object being drawn. When used in conjunction with a Render Texture it allows for effects that require you to erase parts of the texture, in either Canvas or WebGL. When used with a transparent game canvas, it allows you to erase parts of the canvas, showing the web page background through.
  • BlendModes.SOURCE_IN is a new Canvas-only blend mode that allows you to use the source-in composite operation when rendering Game Objects.
  • BlendModes.SOURCE_OUT is a new Canvas-only blend mode that allows you to use the source-out composite operation when rendering Game Objects.
  • BlendModes.SOURCE_ATOP is a new Canvas-only blend mode that allows you to use the source-atop composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_OVER is a new Canvas-only blend mode that allows you to use the destination-over composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_IN is a new Canvas-only blend mode that allows you to use the destination-in composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_OUT is a new Canvas-only blend mode that allows you to use the destination-out composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_ATOP is a new Canvas-only blend mode that allows you to use the destination-atop composite operation when rendering Game Objects.
  • BlendModes.LIGHTER is a new Canvas-only blend mode that allows you to use the lighter composite operation when rendering Game Objects.
  • BlendModes.COPY is a new Canvas-only blend mode that allows you to use the copy composite operation when rendering Game Objects.
  • BlendModes.XOR is a new Canvas-only blend mode that allows you to use the xor composite operation when rendering Game Objects.
  • RenderTexture.erase is a new method that will take an object, or array of objects, and draw them to the Render Texture using an ERASE blend mode, resulting in them being removed from the Render Texture. This is really handy for making a bitmap masked texture in Canvas or WebGL (without using an actual mask), or for 'cutting away' part of a texture.
  • There is a new boolean Game Config property called customEnvironment. If set to true it will skip the internal Feature checks when working out which type of renderer to create, allowing you to run Phaser under non-native web environments. If using this value, you must set an explicit renderType of either CANVAS or WEBGL. It cannot be left as AUTO. Fix #4166 (thanks @jcyuan)
  • Animation.nextFrame will advance an animation to the next frame in the sequence instantly, regardless of the animation time or state. You can call this on a Sprite: sprite.anims.nextFrame() (thanks rgk25)
  • Animation.previousFrame will set an animation to the previous frame in the sequence instantly, regardless of the animation time or state. You can call this on a Sprite: sprite.anims.previousFrame() (thanks rgk25)
  • Geom.Intersects.PointToLine has a new optional argument lineThickness (which defaults to 1). This allows you to determine if the point intersects a line of a given thickness, where the line-ends are circular (not square).
  • Geom.Line.GetNearestPoint is a new static method that will return the nearest point on a line to the given point.
  • Geom.Line.GetShortestDistance is a new static method that will return the shortest distance from a line to the given point.
  • Camera.getBounds is a new method that will return a rectangle containing the bounds of the camera.
  • Camera.centerOnX will move the camera horizontally to be centered on the given coordinate without changing its vertical placement.
  • Camera.centerOnY will move the camera vertically to be centered on the given coordinate without changing its horizontally placement.
  • AnimationManager.exists is a new method that will check to see if an Animation using the given key already exists or not and returns a boolean.
  • animationstart-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationstart-explode.
  • animationrestart-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationrestart-explode.
  • animationcomplete-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationcomplete-explode.
  • animationupdate-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationupdate-explode.
  • The Animation class now extends the Event Emitter and dispatches events itself. This allows you to listen for events from a specific Animation, rather than via a Game Object. This is handy, for example, if you had an explosion animation that you wanted to trigger a sound effect when it started. You can now listen for the events from the Animation object directly.
  • The Animation class now emits the start event when played (either forward, or in reverse) by any Game Object.
  • The Animation class now emits the restart event when it restarts playing on any Game Object.
  • The Animation class now emits the complete event when it finishes playing on any Game Object.
  • The Animation Component has a new method called chain which allows you to line-up another animation to start playing as soon as the current one stops, no matter how it stops (either by reaching its natural end, or directly by having stop called on it). 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 callback). 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.
  • CanvasTexture.drawFrame is a new method that allows you to draw a texture frame to the CanvasTexture based on the texture key and frame given.
  • CanvasTexture.getIndex is a new method that will take an x/y coordinate and return the Image Data index offset used to retrieve the pixel values.
  • CanvasTexture.getPixels is a new method that will take a region as an x/y and width/height and return all of the pixels in that region from the CanvasTexture.
  • CanvasTexture.setPixel is a new method that sets the given pixel in the CanvasTexture to the color and alpha values provided.
  • CanvasTexture.getData is a new method that will extract an ImageData block from the CanvasTexture from the region given.
  • CanvasTexture.putData is a new method that will put an ImageData block at the given coordinates in a CanvasTexture.
  • Line.Extend is a new static function that allows you extend the start and/or end points of a Line by the given amounts.
  • Vector2.LEFT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.RIGHT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.UP is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.DOWN is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.ONE is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.ZERO is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.LEFT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.RIGHT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.UP is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.DOWN is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.FORWARD is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.BACK is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.ONE is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Geometery Mask has a new property called invertAlpha in WebGL, which works in the same way as the flag on the Bitmap Mask and allows you to invert the function of the stencil buffer, i.e. non-drawn shapes become invisible, and drawn shapes visible (thanks @tfelix)
  • The Arcade Physics Body has a new property maxSpeed which limits the vector length of the Body velocity. You can set it via the method setMaxSpeed and it is applied in the World.computeVelocity method (thanks @Edwin222 @rexrainbow)
  • WebGLRenderer.snapshotArea is a new method that allows you to grab an image of the given region of the canvas during the post-render step and have it sent to your defined callback. This is the same as snapshot except you control the area being grabbed, so is more efficient if you only need a smaller area.
  • WebGLRenderer.snapshotPixel is a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as a Color object to your specified callback.
  • CanvasRenderer.snapshotArea is a new method that allows you to grab an image of the given region of the canvas during the post-render step and have it sent to your defined callback. This is the same as snapshot except you control the area being grabbed, so is more efficient if you only need a smaller area.
  • CanvasRenderer.snapshotPixel is a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as a Color object to your specified callback.
  • SceneManager.getScenes is a new method that will return all current Scenes being managed by the Scene Manager. You can optionally return only active scenes and reverse the order in which they are returned in the array.
  • DOM.GetTarget is a new helper function that will return a reference to a DOM Element based on the given string or node.
  • GameObjects.Extern is a new special type of Game Object that allows you to pass rendering off to a 3rd party. When you create an Extern and place it in the display list of a Scene, the renderer will process the list as usual. When it finds an Extern it will flush the current batch, clear down the pipeline and prepare a transform matrix which your render function can take advantage of, if required. The Extern Game Object is used heavily by the Spine Plugin, but can also be used by other libraries such as three.js, allowing them to render directly into a Phaser game.

Updates

  • You can now modify this.physics.world.debugGraphic.defaultStrokeWidth to set the stroke width of any debug drawn body, previously it was always 1 (thanks @samme)
  • TextStyle.setFont has a new optional argument updateText which will sets if the text should be automatically updated or not (thanks @DotTheGreat)
  • ProcessQueue.destroy now sets the internal toProcess counter to zero.
  • The PathFollower.pathRotationVerticalAdjust property has been removed. It was supposed to flipY a follower when it reversed path direction, but after some testing it appears it has never worked and it's easier to do this using events, so the property and associated config value are removed. The verticalAdjust argument from the setRotateToPath method has been removed as well.
  • The config value preserveDrawingBuffer has been removed as it has never been used by the WebGL Renderer.
  • PluginManager.install returns null if the plugin failed to install in all cases.
  • PluginFile will now install the plugin into the current Scene as long as the start or mapping arguments are provided.
  • MATH_CONST no longer requires or sets the Random Data Generator, this is now done in the Game Config, allowing you to require the math constants without pulling in a whole copy of the RNG with it.
  • The Dynamic Bitmap Text Canvas Renderer was creating a new data object every frame for the callback. It now uses the callbackData object instead, like the WebGL renderer does.
  • WebGLRenderer.setBlendMode has a new optional argument force, which will force the given blend mode to be set, regardless of the current settings.
  • The method DisplayList.sortGameObjects has been removed. It has thrown a runtime error since v3.3.0(!) which no-one even spotted which is a good indication of how little the method was used. The display list is automatically sorted anyway, so if you need to sort a small section of it, just use the standard JavaScript Array sort method (thanks ornyth)
  • The method DisplayList.getTopGameObject has been removed. It has thrown a runtime error since v3.3.0(!) which no-one even spotted which is a good indication of how little the method was used (thanks ornyth)
  • WebGLRenderer.setFramebuffer has a new optional boolean argument updateScissor, which will reset the scissor to match the framebuffer size, or clear it.
  • WebAudioSoundManager.onFocus will not try to resume the Audio Context if it's still locked.
  • WebAudioSoundManager.onBlur will not try to suspend the Audio Context if it's still locked.
  • When using ScenePlugin.add, to add a new Scene to the Scene Manager, it didn't allow you to include the optional Scene data object. You can now pass this in the call (thanks @kainage)
  • Graphics.stroke is a new alias for the strokePath method, to keep the calls consistent with the Canvas Rendering Context API.
  • Graphics.fill is a new alias for the fillPath method, to keep the calls consistent with the Canvas Rendering Context API.
  • LoaderPlugin.sceneManager is a new property that is a reference to the global Scene Manager, useful for Plugins.
  • Whenever Camera.roundPixels was enabled it would use a bitwise operation to truncate the float (x |= 0) - this has been replaced across all files that used it, with a call to Math.round instead. This gives far better results when zooming cameras both in and out of a Scene, stopping thin gaps appearing between closely packed Game Objects.
  • AnimationManager.create will now return a boolean false if the given key is invalid (i.e. undefined or falsey).
  • AnimationManager.create will no longer raise a console warning if the animation key is already in use. Instead, it will return the animation belonging to that key. A brand new animation will only be created if the key isn't already in use. When this happens, the add event is emitted by the Animation Manager. If no event is emitted, the animation already existed.
  • ArcadePhysics.Body.destroy will now only add itself to the World pendingDestroy list if the world property exists. This prevents Cannot read property 'pendingDestroy' of undefined errors if you try to delete a physics body in a callback and then immediately change Scene (which tells the physics work to also delete all bodies)
  • The Animation Component restart method has had is sole key argument removed. Previously, you had to pass in the key of the animation you wished to reverse, but now you can just call the method directly, and as long as there is an animation playing, it will automatically start playing in reverse, without the nee for a key (the way it should have been originally)
  • Animation.play and playReverse will now accept either a string-based key of the animation to play (like before), or you can pass in an Animation instance, and it will play that animation.
  • CanvasTexture.clear now has 4 new optional arguments: x, y, width, height which allow you to define the region of the texture to be cleared. If not provided it will clear the whole texture, which is the same behavior as before.
  • EarCut, the polygon triangulation library used by the Graphics and WebGL classes, has been upgraded from 2.1.1 to 2.1.4. 2.1.2 fixed a few race conditions where bad input would cause an error. 2.1.3 improved performance for bigger inputs (5-12%) and 2.1.4 fixed a race condition that could lead to a freeze on degenerate input.
  • TextureTintPipeline.batchQuad and batchTri have two new optional arguments texture and unit which are used to re-set the batch texture should the method cause a batch flush.
  • TextureTintPipeline.requireTextureBatch is a new internal method that helps speed-up the creation of texture batches. It is used in conjunction with setTexture2D and pushBatch.
  • TextureTintPipeline.flush and TextureTintPipeline.pushBatch have been optimized to handle zero based texture units as priority. They've also been refactored to avoid creation of empty texture batches.
  • The WebGLRenderer.setTexture2D method has a new optional argument flush which controls if the pipeline is flushed if the given texture is new, or not. This is used internally to skip flushing during an existing flush.
  • The Tilemap Layer width and height properties are now based on the tilemap tile sizes multiplied by the layer dimensions. This corrects an issue with layer sizes being wrong if you called setBaseTileSize on a Map.
  • The WebGLRenderer will now clear the framebuffer at the start of every render.
  • WebGLRenderer.setScissor now has a new optional argument drawingBufferHeight which allows you to specify the drawing buffer height, rather than use the renderers default value.
  • WebGLRenderer.pushScissor now has a new optional argument drawingBufferHeight which allows you to specify the drawing buffer height, rather than use the renderers default value.
  • WebGLRenderer.preRender now calls gl.clearColor in order to restore the background clear color in case something, like a Render Texture, has changed it.
  • Map.set will now update an existing value if you provide it with a key that already exists within the Map. Previously, if you tried to set the value of a key that existed it would be skipped.
  • MatterSprite would set its type property to be Image. It now sets it to be Sprite as it should do.
  • Matter.TileBody.setFromTileCollision no longer checks if the shape is concave or convex before modifying the vertices, as the update to the Matter.js lib in 3.12 stopped this from working with Tiled collision shapes.
  • The Scene transitionstart event is now dispatched by the Target Scene of a transition, regardless if the Scene has a create method or not. Previously, it was only dispatched if the Scene had a create method.
  • The Loader will now allow an XHR status of 0 as success too. Normally only status 200 would be accepted as success, but 0 is returned when a file is loaded from the local filesystem (file://). This happens, for example, when opening the index.html of a game in a browser directly, or when using Cordova on iOS. Fix #3464 (thanks @Ithamar)
  • Tween.restart now returns the Tween instance (thanks @rexrainbow)
  • Tween.play now returns the Tween instance (thanks @rexrainbow)
  • Tween.seek now returns the Tween instance (thanks @rexrainbow)
  • Tween.complete now returns the Tween instance (thanks @rexrainbow)
  • Tween.stop now returns the Tween instance (thanks @rexrainbow)
  • List.sort now has an optional parameter handler which allows you to provide your own sort handling function (thanks @jcyuan)
  • Container.sort now has an optional parameter handler which allows you to provide your own sort handling function (thanks @jcyuan)
  • The WebGLRenderer method canvasToTexture will now only set the filter to be NEAREST if antialias is disabled in the game config (i.e. when running in pixelArt mode). This means that Text objects, and other Canvas backed textures, now render with anti-aliasing if everything else does. You can disable this on a per-object basis by calling texture.setFilter(1) on them.
  • CanvasRenderer.snapshotCallback, snapshotType and snapshotEncoder have all been removed as they are no longer required.
  • CanvasRenderer.snapshotState is a new object that contains the snapshot configuration data, the same as the WebGL Renderer.
  • The signature of the WebGLSnapshot function has changed. It now takes a Snapshot Configuration object as the second parameter.
  • The signature of the CanvasSnapshot function has changed. It now takes a Snapshot Configuration object as the second parameter.
  • A Tween Timeline will now set it's internal destroy state before calling either the onComplete callback or sending the COMPLETE event. This means you can now call methods that will change the state of the Timeline, such as play, during the callback handlers, where-as before doing this would have had the internal state changed immediately, preventing it (thanks Lucas Knight)
  • The AddToDOM method has had the overflowHidden argument removed. The DOM element the canvas is inserted into no longer has overflow: hidden applied to its style. If you wish to have this, please add it directly via CSS.

Bug Fixes

  • The Rectangle Shape object wouldn't render if it didn't have a stroke, or any other objects on the display list (thanks mliko)
  • When using a font string instead of setting fontFamily, fontSize and fontStyle in either Text.setStyle or setFont, the style properties wouldn't get set. This isn't a problem while creating the text object, only if modifying it later (thanks @DotTheGreat)
  • Text.toJSON wasn't saving the font style when using the "font" shorthand to create it. It now saves it correctly. Fix #4141 (thanks @divillysausages)
  • Disabling camera bounds and then moving the camera to an area in a Tilemap that did not have any tile information would throw an Uncaught Reference error as it tried to access tiles that did not exist (thanks @Siyalatas)
  • Fixed an issue where Sprite Sheets being extracted from a texture atlas would fail if the sheet was either just a single column or single row of sprites. Fix #4096 (thanks @Cirras)
  • If you created an Arcade Physics Group without passing a configuration object, and passing an array of non-standard children, it would throw a classType runtime error. It now creates a default config object correctly (thanks @pierpo)
  • The Camera.cull method has been restructured so it now calculates if a Game Object is correctly in view or not before culling it. Although not used internally, if you need to cull objects for a camera, you can now safely use this method. Fix #4092 (thanks @Cirras)
  • The Tiled Parser would ignore animated tile data if it was in the new Tiled 1.2 format. This is now accounted for, as well as 1.0 (thanks @nkholski)
  • Array.Matrix.ReverseRows was actually reversing the columns, but now reverses the rows.
  • Array.Matrix.ReverseColumns was actually reversing the rows, but now reverses the columns.
  • UnityAtlas now sets the correct file type key if using a config file object.
  • Starting with version 3.13 in the Canvas Renderer, it was possible for long-running scripts to start to get bogged-down in fillRect calls if the game had a background color set. The context is now saved properly to avoid this. Fix #4056 (thanks @Aveyder)
  • Render Textures created larger than the size of the default canvas would be automatically clipped when drawn to in WebGL. They now reset the gl scissor and drawing height property in order to draw to their full size, regardless of the canvas size. Fix #4139 (thanks @chaoyang805 @iamchristopher)
  • The cameraFilter property of a Game Object will now allow full bitmasks to be set (a value of -1), instead of just those > 0 (thanks @stuartkeith)
  • The PathFollower.startFollow method now properly uses the startAt argument to the method, so you can start a follower off at any point along the path. Fix #3688 (thanks @DannyT @diteix)
  • Static Circular Arcade Physics Bodies now render as circles in the debug display instead of showing their rectangle bounds (thanks @maikthomas)
  • Changing the mute flag on an HTML5AudioSound instance, via the mute setter, now works as it does via the Sound Manager (thanks @Waclaw-I @neon-dev)
  • Changing the volume on an HTML5AudioSound instance, via the volume setter, now works as it does via the Sound Manager (thanks @Waclaw-I)
  • The Dynamic Tilemap Layer WebGL renderer was drawing tiles at the incorrect position if the layer was scaled. Fix #4104 (thanks @the-realest-stu)
  • Tile.tileset now returns the specific Tileset associated with the tile rather than an array of them. Fix #4095 (thanks @quadrupleslap)
  • Tile.getCollisionGroup wouldn't return the correct Group after the change to support multiple Tilesets. It now returns the group properly (thanks @jbpuryear)
  • Tile.getTileData wouldn't return the correct data after the change to support multiple Tilesets. It now returns the tile data properly (thanks @jbpuryear)
  • The GetTileAt and RemoveTileAt components would error with "Cannot read property 'index' of undefined" if the tile was undefined rather than null. It now handles both cases (thanks @WaSa42)
  • Changing TileSprite.width or TileSprite.height will now flag the texture as dirty and call updateDisplayOrigin, allowing you to resize TileSprites dynamically in both Canvas and WebGL.
  • RandomDataGenerator.shuffle has been fixed to use the proper modifier in the calculation allowing for a more even distribution (thanks wayfinder)
  • The Particle Emitter was not recycling dead particles correctly so it was creating new objects every time it emitted (the old particles were then left to the browsers gc to clear up). This has now been recoded so the emitter will properly keep track of dead particles and re-use them (thanks @Waclaw-I for the initial PR)
  • ParticleEmitter.indexSortCallback has been removed as it's no longer required.
  • Particle.index has been removed as it's no longer required. Particles don't need to keep track of their index any more.
  • The Particle Emitter no longer needs to call the StableSort.inplace during its preUpdate, saving cpu.
  • Particle.resetPosition is a new method that is called when a particle dies preparing it for firing again in the future.
  • The Canvas SetTransform method would save the context state, but it wasn't restored at the end in the following Game Objects: Dynamic Bitmap Text, Graphics, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. These now all restore the context, meaning if you're using non-canvas sized cameras in Canvas mode, it will now render beyond just the first custom camera.
  • Utils.Array.MoveUp wouldn't let you move an array element to the top-most index in the array. This also impacted Container.moveUp.
  • The Texture Tint Pipeline had a logic error that would cause every 2001st quad to either be invisible, or pick-up the texture of the 2000th quad by mistake. The batchQuad and batchTri methods how handle re-assigning the batch texture if they cause a batch flush as part of their process.
  • Rotating Sprites that used a Normal Map wouldn't rotate the normal map with it causing the lighting effects to become irregular. The normal map vectors are now rotated correctly (thanks @sercant for the PR and @fazzamatazz and @ysraelJMM for the report)
  • Changing scaleX or scaleY on a MatterImage or MatterSprite would cause the body scale to become distorted as the setters didn't use the correct factor when resetting the initial scale. Fix #4206 (thanks @YannCaron)
  • StaticBody.reset in Arcade Physics would ignore the x and y values given to it. If given, they're now used to reset the parent Game Object before the body is updated. Fix #4224 (thanks @samme)
  • Static Tilemap Layers wouldn't render correctly if the layer used a tileset with a different size to the base map data (set via setBaseTileSize). They now render correctly in WebGL and Canvas regardless of the base tile size.
  • When using RenderTexture.fill, the alpha argument would be ignored in Canvas mode. It's now used when filling the RenderTexture.
  • Fixed an issue in WebGLRenderer.setScissor where it was possible to try and compare the scissor size to a non-current scissor if called outside of the render loop (i.e. from RenderTexture.fill) (thanks @hackhat)
  • RenderTexture.fill in WebGL would use gl.clear and a clear color to try and fill the Render Texture. This only worked for full-canvas sized RenderTextures that didn't have a camera zoom applied. It has now been swapped to use the drawFillRect method of the Texture Tint Pipeline, allowing it to work properly regardless of camera zoom or size.
  • Container.getFirst was using an incorrect Array Utils function GetFirstElement when it should have been using GetFirst. It now uses the correct function. Fix #4244 (thanks @miran248)
  • List.getFirst was using an incorrect Array Utils function GetFirstElement when it should have been using GetFirst. It now uses the correct function. Fix #4244 (thanks @miran248)
  • Fixed an issue where changing the viewport or size of a Camera belonging to a RenderTexture wouldn't impact the rendering and objects will still render outside of the viewport range. It's now converted to a proper gl scissor rect by the renderer, meaning you can limit the area rendered to by adjusting the internal Render Texture cameras viewport. Fix #4243 (thanks @hackhat)
  • CanvasTexture.destroy is a new method that specifically handles the destruction of the CanvasTexture and all of its associated typed arrays. This prevents a memory leak when creating and destroying lots of RenderTextures (which are CanvasTexture backed). Fix #4239 (thanks @sjb933)
  • The Alpha, Flip and Origin components have been removed from the Mesh Game Object (and by extension, Quad as well) as they are not used in the renderer and should be manipulated via the Mesh properties. Fix #4188 (thanks @enriqueto)
  • The processDomCallbacks method in the Input Manager wasn't correctly clearing the once arrays. Responsibility for this has now been passed to the queue methods queueTouchStart, queueTouchMove, queueTouchEnd, queueMouseDown, queueMouseMove and queueMouseUp. Fix #4257 (thanks @iArePJ)
  • Arcade Physics now manages when postUpdate should be applied better, stopping it from gaining a zero delta during a further check in the same frame. This fixes various issues, including the mass collision test demo. Fix #4154 (thanks @samme)
  • Arcade Physics could trigger a collide event on a Body even if it performing an overlap check, if the onCollide property was true (thanks @samme)
  • TileSprites no longer cause a crash when using the Headless mode renderer. Fix #4297 (thanks @clesquir)
  • The WebGLRenderer will now apply a transparent background if transparent = true in the game config (thanks @gomachan7)
  • List.sort was missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)
  • Container.sort was missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)
  • DataManager.pop would emit the DataManager instance, instead of the parent, as the first event argument. It now emits the parent as it should do. Fix #4186 (thanks @gadelan)
  • The GetValue function wasn't checking for the existance of '.' in the config property name correctly, causing the branch to always be taken (thanks @kyranet)
  • Safari had permission problems playing HTML5 Audio files on Mac OS. Due to the changes in the input event system audio now plays properly based on user interactions. You still can't play it automatically, though, it will always require a user gesture to begin. Fix #4217 (thanks @increpare)

Examples and TypeScript

Thanks to the following for helping with the Phaser 3 Examples and TypeScript definitions, either by reporting errors, or even better, fixing them:

@guilhermehto @samvieten @darkwebdev @RoryO @snowbillr @slothyrulez @jcyuan @jestarray @CzBiX

Phaser Doc Jam

The Phaser Doc Jam was a community-backed effort to try and get the Phaser 3 API documentation to 100% coverage. The Doc Jam is now over and I offer my thanks to the following who helped with docs in this release:

@16patsle - @gurungrahul2 - @icbat - @samme - @telinc1 - anandu pavanan - blackhawx - candelibas - Diego Romero - doronlinder - Elliott Wallace - eric - Georges Gabereau - Haobo Zhang - henriacle - jak6jak - Jake Jensen - James Van Roose - JamesSkemp - joelahoover - Joey - madclaws - marc136 - Mihail Ilinov - naum303 - NicolasRoehm - nuane - rejacobson - Robert Kowalski - rodri042 - rootasjey - sawamara - scottwestover - sir13tommy - stetso - therealsamf - Tigran - willblackmore - zenwaichi

Also, the following helped with the docs outside of the Doc Jam:

@bryanwood @jestarray @matosummer @tfelix @imilo @BigZaphod @OmarShehata @16patsle @jcyuan @iam13islucky @FractalBobz Endre

- JavaScript
Published by photonstorm over 7 years ago

phaser - Phaser v3.16.0 Release Candidate 3

The final Scale Manager functionality is included, lots of JSDoc fixes (so the TypeScript defs now generate again) and masses of other small tweaks.

- JavaScript
Published by photonstorm over 7 years ago

phaser - Phaser v3.16.0 Release Candidate 2

The second release candidate fixes issues with the new input system across multiple Scenes, as well as fixing keyboard input outside of the legacy handler.

It also puts the Externs back as first class Game Objects and fixes numerous other issues which can be found in the Change Log.

- JavaScript
Published by photonstorm over 7 years ago

phaser - Phaser v3.16.0 Release Candidate 1

Facebook Instant Games Updates and Fixes

  • Added the Leaderboard.getConnectedScores method, to get a list of scores from player connected entries.
  • The loadPlayerPhoto function in the Instant Games plugin now listens for the updated Loader event correctly, causing the photocomplete event to fire properly.
  • Leaderboard.setScore now emits the LeaderboardScore object with the setscore event, as the documentation said it did.
  • Leaderboard.getPlayerScore now only populates the playerScore property if the entry isn't null.
  • If the setScore or getPlayerScore calls fail, it will return null as the score instance, instead of causing a run-time error.
  • You can now pass an object or a string to setScore and objects will be automatically stringified.
  • The preloadAds method will now only create an AdInstance object if the interstitial loadSync promise resolves.
  • The preloadVideoAds method will now only create an AdInstance object if the interstitial loadSync promise resolves.
  • The preloadAds method will now emit the adsnofill event, if there are no ads in the inventory to load.
  • The preloadVideoAds method will now emit the adsnofill event, if there are no ads in the inventory to load.
  • The showAd method will now emit the adsnotloaded event, if there are no ads loaded matching the given Placement ID.
  • The showVideo method will now emit the adsnotloaded event, if there are no ads loaded matching the given Placement ID.
  • Showing an ad will emit the adfinished event when the ad is closed, previously this event was called showad but the new name better reflects what has happened.
  • The Facebook Plugin is now available in the Phaser.Scene class template under the facebook property (thanks @bryanwood)
  • Fixed the Leaderboard.getScores method to now take the arguments into account. Fix #4271 (thanks @Oramy)
  • Fixed an API validation error in the chooseContext method. Fix #4248 (thanks @yadurajiv)

Important Changes to the Input System

In Phaser 3.15 and earlier the Input system worked using an event queue. All native DOM input events, such as from the Mouse, Touch or Keyboard, were picked up by event handlers and stored in a queue within the Input Manager. This queue was then processed during the next game step, all the events were dealt with and then it was cleared, ready to receive more events. As they were processed, the internal Phaser events such as pointerdown or keyup were dispatched to your game code.

This worked fine in that you were able to guarantee exactly when the events would arrive, because it was always at the same time in the game step. However, it had the side effect of you not being able to do things like open external browser windows, or go into Full Screen mode, during your event handlers - because they weren't "real" events, so didn't pass the browser security checks. To this end, methods like addUpCallback were added to try and provide this support (although it was never possible for keyboard events).

In 3.16 this has changed. The DOM Events now trigger the respective internal events immediately, in the same invocation. So if you click on the canvas, the pointerdown event you receive in your game is still part of the 'native' event handler, so you're now free to do things like go into full screen mode, or open external windows, without any browser warnings or work-arounds.

It does, however, mean that the point at which these handlers are called is no longer always consistent, and is no longer bound to the speed of the Request Animation Frame update. We've tested as much as possible, and so far, things carry on working as before. We've noticed a slight increase in responsiveness, due to the removal of the fractional delay in processing the events, which feels good. However, if for whatever reason this change has broken your game then you're able to easily switch back to the previous version. In your Game Config, create an input object and give it the property queue: true. This will tell Phaser to use the legacy event queue system.

Please note that we will remove this legacy system in the near future. So, please try and adapt your games to use the new system. If you've found an edge-case where something breaks because of it, please report it so we can look into it.

As a result of this change, the following are now deprecated:

  • InputPlugin.addUpCallback method.
  • InputPlugin.addDownCallback method.
  • InputPlugin.addMoveCallback method.
  • InputManager.queue property.
  • InputManager.domCallbacks property.
  • InputManager._hasUpCallback property.
  • InputManager._hasDownCallback property.
  • InputManager._hasMoveCallback property.
  • InputManager.processDomCallbacks method.
  • InputManager.addUpCallback method.
  • InputManager.addDownCallback method.
  • InputManager.addMoveCallback method.

keydown and keyup changes

Due to unification across the event system, the keydown_ and keyup_ dynamic event strings have changed.

  • In all cases the keydown_KEY event name has changed to keydown-KEY. Note the change from an underscore to a hyphen.
  • In all cases the keyup_KEY event name has changed to keyup-KEY. Note the change from an underscore to a hyphen.

You should update your game code accordingly.

Keyboard Input - New Features

The specificity of the Keyboard events has been changed to allow you more control over event handling. Previously, the Keyboard Plugin would emit the global keydown-CODE event first (where CODE was a keycode string, like keydown-A), then it would emit the global keydown event. In previous versions, Key objects, created via this.input.keyboard.addKey(), didn't emit events.

The Key class now extends EventEmitter and emits two new events directly: down and up. This means you can listen for an event from a Key you've created, i.e.: yourKey.on('up', handler).

The order has also now changed. If it exists, the Key object will dispatch its down event first. Then the Keyboard Plugin will dispatch keydown_CODE and finally the least specific of them all, keydown will be dispatched.

You also now have the ability to cancel this at any stage either on a local or global level. All event handlers are sent an event object which you can call event.stopImmediatePropagation() on. This will immediately stop any further listeners from being invoked in the current Scene. Therefore, if you call stopImmediatePropagation() in the Key.on handler, then the Keyboard Plugin will not emit either the keydown-CODE or keydown global events. You can also call stopImmediatePropagation() during the keydown-CODE handler, to stop it reaching the global keydown handler. As keydown is last, calling it there has no effect.

There is also the stopPropagation() function. This works in the same way as stopImmediatePropagation but instead of being local, it works across all of the Scenes in your game. For example, if you had 3 active Scenes (A, B and C, with A at the top of the Scene list), all listening for the same key, calling stopPropagation() in Scene A would stop the event from reaching any handlers in Scenes B or C. Remember that events flow down the Scene list from top to bottom. So, the top-most rendering Scene in the Scene list has priority over any Scene below it.

All the above also works for keyup events.

New in 3.16 is the ability to receive a global keydown or keyup event from any key on the keyboard. Previously, it would only emit the event if it came from one of the keys listed in the KeyCodes file. Now, those global events will fire for any key, regardless of location.

Keyboard Captures

Key capturing is the way in which you stop a keyboard DOM event from activating anything else in the browser by calling preventDefault on it. For example, in tall web pages, pressing the SPACE BAR causes the page to scroll down. Obviously, if this is also the fire or jump button in your game, you don't want this to happen. So the key needs to be 'captured' to prevent it. Equally, you may wish to also capture the arrow keys, for similar reasons. Key capturing is done on a global level. If you set-up the capture of a key in one Scene, it will be captured globally across the whole game.

In 3.16 you now do this using the new KeyboardPlugin.addCapture method. This takes keycodes as its argument. You can either pass in a single key code (i.e. 32 for the Space Bar), an array of key codes, or a comma-delimited string - in which case the string is parsed and each code it can work out is captured.

To remove a capture you can use the KeyboardPlugin.removeCapture method, which takes the same style arguments as adding captures. To clear all captures call KeyboardPlugin.clearCaptures. Again, remember that these actions are global.

You can also temporarily enable and disable capturing using KeyboardPlugin.enableGlobalCapture and KeyboardPlugin.disableGlobalCapture. This means if you set-up a bunch of key captures, but then need to disable them all for a while (perhaps you swap focus to a DOM text field), you can call disableGlobalCapture to do this, and when finished in the DOM you can enable captures again with enableGlobalCapture, without having to clear and re-create them all.

Default captures can be defined in the Game Config in the input.keyboard.captures object. The captures are actually stored in the KeyboardManager class. The KeyboardPlugin is just a proxy to methods in the Keyboard Manager, but is how you should interface with it.

  • KeyboardPlugin.addCapture is a new method that allows you to define a set of keycodes to have the default browser behaviors disabled on.
  • KeyboardPlugin.removeCapture is a new method that removes specific previously set key captures.
  • KeyboardPlugin.clearCaptures is a new method that removes all key captures.
  • KeyboardPlugin.getCaptures is a new method that returns an array of all current key captures.
  • KeyboardPlugin.enableGlobalCapture is a new method that enables any key captures that have been created.
  • KeyboardPlugin.disableGlobalCapture is a new method that disables any key captures that have been created, without removing them from the captures list.
  • KeyboardPlugin.addKey has a new boolean argument enableCapture, which is true by default, that will add a key capture for the Key being created.
  • KeyboardPlugin.addKeys has a new boolean argument enableCapture, which is true by default, that will add a key capture for any Key created by the method.

Other Keyboard Updates and Fixes

  • There is a new class called KeyboardManager. This class is created by the global Input Manager if keyboard access has been enabled in the Game config. It's responsible for handling all browser keyboard events. Previously, the KeyboardPlugin did this which meant that every Scene that had its own Keyboard Plugin was binding more native keyboard events. This was causing problems with parallel Scenes when needing to capture keys. the KeyboardPlugin class still exists, and is still the main point of interface when you call this.input.keyboard in a Scene, but DOM event handling responsibility has been taken away from it. This means there's now only one set of bindings ever created, which makes things a lot cleaner.
  • There is a new Game and Scene Config setting input.keyboard.capture which is an array of KeyCodes that the Keyboard Plugin will capture all non-modified key events on. By default it is empty. You can populate it in the config, or use the new capture methods.
  • The Keyboard Manager will now call preventDefault only on non-modified key presses, stopping the keyboard event from hitting the browser. Previously, capturing the R key, for example, would block a CTRL+R page reload, but it now ignores it because of the key modifier.
  • If the browser Window loses focus, either from switching to another app, or another tab, all active Keys will be reset. This prevents issues with keys still reporting as being held down after leaving the game and returning to it again. Fix #4134 (thanks @Simplonium)
  • Key.emitOnRepeat is a new boolean property that controls if the 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).
  • Key.setEmitOnRepeat is a new chainable method for setting the emitOnRepeat property.
  • The KeyboardPlugin.addKeys method has a new optional boolean emitOnRepeat which sets that property on all Key objects it creates as part of the call. It defaults to false.
  • The KeyboardPlugin.addKey method has a new optional boolean emitOnRepeat which sets that property on the Key object it creates. It defaults to false.
  • The Key class now extends EventEmitter and emits two events directly: down and up. This means you can listen for an event from a Key you've created, i.e.: yourKey.on('up', handler).
  • The following Key Codes have been added, which include some missing alphabet letters in Persian and Arabic: SEMICOLON_FIREFOX, COLON, COMMA_FIREFOX_WINDOWS, COMMA_FIREFOX, BRACKET_RIGHT_FIREFOX and BRACKET_LEFT_FIREFOX (thanks @wmateam)
  • Key.onDown is a new method that handles the Key being pressed down, including down repeats.
  • Key.onUp is a new method that handles the Key being released.
  • Key.destroy is a new method that handles Key instance destruction. It is called automatically in KeyboardPlugin.destroy.
  • The Key.preventDefault property has been removed. This is now handled by the global keyboard capture methods.
  • Key.metaKey is a new boolean property which indicates if the Meta Key was held down when the Key was pressed. On a Mac the Meta Key is Command. On a Windows keyboard, it's the Windows key.
  • InputManager.keyboard is a new property that instantiates the global Keyboard Manager, if enabled in the game config.
  • The KeyboardPlugin.addKey method has a new boolean property enableCapture which automatically prevents default on the Key being created.
  • The KeyboardPlugin.addKeys method has a new boolean property enableCapture which automatically prevents default on Keys being created.
  • Phaser.Input.Keyboard.ProcessKeyDown has been removed as it's no longer required, Key.onDown handles it instead.
  • Phaser.Input.Keyboard.ProcessKeyUp has been removed as it's no longer required, Key.onUp handles it instead.
  • The Keyboard Manager has a property called captures which is an array of keycodes, as populated by the Game Config. Any key code in the array will have preventDefault called on it if pressed.
  • KeyboardPlugin.manager is a new property that references the Keyboard Manager and is used internally.
  • KeyboardPlugin.target has been removed as it's no longer used by the class.
  • KeyboardPlugin.queue has been removed as it's no longer used by the class.
  • KeyboardPlugin.onKeyHandler has been removed as it's no longer used by the class.
  • KeyboardPlugin.startListeners has been removed as it's no longer used by the class.
  • KeyboardPlugin.stopListeners has been removed as it's no longer used by the class.

Mouse and Touch Input - New Features, Updates and Fixes

  • The Mouse Manager class has been updated to remove some commented out code and refine the startListeners method.
  • When enabling a Game Object for input it will now use the width and height properties of the Game Object first, falling back to the frame size if not found. This stops a bug when enabling BitmapText objects for input and it using the font texture as the hit area size, rather than the text itself.
  • Pointer.smoothFactor is a float-value that allows you to automatically apply smoothing to the Pointer position as it moves. This is ideal when you want something smoothly tracking a pointer in a game, or are need a smooth drawing motion for an art package. The default value is zero, meaning disabled. Set to a small number, such as 0.2, to enable.
  • Config.inputSmoothFactor is a new property that allows you to set the smoothing factor for all Pointers the game creates. The default value is zero, which is disabled. Set in the game config as input: { smoothFactor: value }.
  • InputManager.transformPointer has a new boolean argument wasMove, which controls if the pointer is being transformed after a move or up/down event.
  • Pointer.velocity is a new Vector2 that contains the velocity of the Pointer, based on the current and previous positions. The velocity is smoothed out each frame according to the Pointer.motionFactor property. This is done for more accurate gesture recognition. The velocity is updated based on Pointer movement and doesn't require a button to be pressed first.
  • Pointer.angle is a new property that contains the angle of the Pointer, in radians, based on the current and previous positions. The angle is smoothed out each frame according to the Pointer.motionFactor property. This is done for more accurate gesture recognition. The angle is updated based on Pointer movement and doesn't require a button to be pressed first.
  • Pointer.distance is a new property that contains the distance of the Pointer, in radians, based on the current and previous positions. The distance is smoothed out each frame according to the Pointer.motionFactor property. This is done for more accurate gesture recognition. The distance is updated based on Pointer movement and doesn't require a button to be pressed first.
  • Pointer.motionFactor is a new property that controls how much smoothing to apply to the Pointer positions each frame. This value is passed to the Smooth Step Interpolation that is used to calculate the velocity, angle and distance of the Pointer. It's applied every frame until the midPoint reaches the current position of the Pointer. The default value is 0.2.
  • The Input Plugin was emitting a preUpdate event, with the capital U, instead of preupdate. This has now been corrected. Fix #4185 (thanks @gadelan)
  • Pointer.updateMotion is a new method that is called automatically, each step, by the Input Manager. It's responsible for calculating the Pointer velocity, angle and distance properties.
  • Pointer.time is a new property that holds the time the Pointer was last updated by the Game step.
  • Pointer.getDistance has been updated. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
  • Pointer.getDistanceX is a new method that will return the horizontal distance between the Pointer's previous and current coordinates. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
  • Pointer.getDistanceY is a new method that will return the horizontal distance between the Pointer's previous and current coordinates. If called while a button is being held down, it will return the distance between the Pointer's current position and it's down position. If called when a Pointer doesn't have a button down, it will return the historic distance between the up and down positions.
  • Pointer.getDuration is a new method that will return the duration the Pointer was held down for. If the Pointer has a button pressed down at the time this method is called, it will return the duration since the Pointer's button was pressed down. If no button is held down, it will return the last recorded duration, based on the time the Pointer button was released.
  • Pointer.getAngle is a new method that will return the angle between the Pointer coordinates. 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.
  • In previous versions, the VisibilityHandler would create a mousedown listener for the game canvas and then call window.focus when detected (assuming the game config autoFocus property was true). Responsibility for this has now been moved to the Mouse Manager onMouseDown handler.
  • In previous versions, the VisibilityHandler would create a mouseout listener for the game canvas and then set game.isOver when detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input Manager isOver property directly.
  • In previous versions, the VisibilityHandler would create a mouseover listener for the game canvas and then set game.isOver when detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input Manager isOver property directly.
  • The Phaser.Game.isOver property has been moved. You can now find it in the Input Manager and it's also accessible via the Input Plugin, which means you can do this.input.isOver from within a Scene. This makes more sense as it's input related and not a game level property.
  • The Input Plugin has a new event you can listen to: gameover, which is triggered whenever the mouse or a pointer is moved over the Game canvas. Listen to it with this.input.on('gameover') from within a Scene.
  • The Input Plugin has a new event you can listen to: gameout, which is triggered whenever the mouse or a pointer leaves the Game canvas. Listen to it with this.input.on('gameout') from within a Scene.
  • The Game used to emit a mouseover event when the mouse entered the game canvas. This is no longer emitted by the Game itself and can instead be listened for using the new Input Plugin event gameover.
  • The Game used to emit a mouseout event when the mouse left the game canvas. This is no longer emitted by the Game itself and can instead be listened for using the new Input Plugin event gameout.
  • If the window object exists (which it will in normal browser environments) new mouseup and touchend event listeners are bound to it and trigger the normal mouseup or touchend events within the internal input system. This means you will now get a pointerup event from the Input Plugin even if the pointer is released outside of the game canvas. Pointers will also no longer think they are still 'down' if released outside the canvas and then moved inside again in their new state.
  • The window will now have focus called on it by the Touch Manager, as well as the Mouse Manager, if the autoFocus game config property is enabled.
  • The Input Plugin has a new event you can listen to: pointerdownoutside, which is triggered whenever the mouse or a pointer is pressed down while outside of the Game canvas. Listen to it with this.input.on('pointerdownoutside') from within a Scene.
  • The Input Plugin has a new event you can listen to: pointerupoutside, which is triggered whenever the mouse or a pointer is released while outside of the Game canvas. Listen to it with this.input.on('pointerupoutside') from within a Scene.
  • Pointer.downElement is a new property that holds the target of the DOM Event that triggered when the Pointer was pressed down. If this is within the game, this will be the game canvas element.
  • Pointer.upElement is a new property that holds the target of the DOM Event that triggered when the Pointer was released. If this is within the game, this will be the game canvas element.
  • The Pointer.dragState property has been removed. This is no longer used internally as it has to be tracked per Scene, not on a global level.
  • InputPlugin.setDragState is a new internal method that sets the drag state for the given Pointer.
  • InputPlugin.getDragState is a new internal method that gets the drag state for the given Pointer.
  • Draggable Game Objects would not work if you had multiple Scenes running in parallel, with draggable objects in both of them. Only the top-most Scene would work fully. Items in the bottom Scene would never finish their drag cycle, causing them to get stuck. Fix #4249 #4278 (thanks @probt @iArePJ)
  • Pointer.leftButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.rightButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.middleButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.backButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.forwardButtonDown will now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).
  • Pointer.up, Pointer.move and Pointer.down now use in to check for the existance of the buttons property on the event, causing it to be set even if equal to zero, which it is when there are no buttons down. This also fixes an issue where the buttons didn't update during a move event (thanks @SonnyCampbell @rexrainbow)

Changes as a result of the new Scale Manager

  • If you set the Game Config property zoom to be > 1 then it will automatically enable pixelArt mode, unless you set pixelArt: false in the config.
  • There is a new property in the Game Config called autoRound, which controls if the canvas size and style sizes are passed through Math.floor or not. On some devices this can help with performance and anti-aliasing. The default is false (turned off).
  • The Game Config property autoResize has been removed as it's now redundant.
  • The WebGL and Canvas Renderers no longer change the Canvas size in their resize methods. They just update internal properties.
  • The WebGL and Canvas Renderers now read the width, height and resolution values from the Scale Manager, not the Game Config.
  • CameraManager.baseScale property has been removed as it's no longer used anywhere.
  • The BaseCamera and Camera preRender methods now only take a resolution argument and use it internally for their transforms.
  • InputManager.scaleManager is a new property that is a reference to the Scale Manager. This is populated in the boot method.
  • The InputManager.transformX method has been removed. This is now available in the ScaleManager.
  • The InputManager.transformY method has been removed. This is now available in the ScaleManager.
  • The InputManager.scale property has been removed. This is now available in the ScaleManager under displayScale.
  • The InputManager.resize method has been removed as this process is now handled by the ScaleManager.
  • The InputManager.bounds property has been removed as this process is now handled by the ScaleManager.
  • The InputManager.updateBounds method has been removed as this process is now handled by the ScaleManager.
  • The InputManager.getOffsetX method has been removed as it's no longer required.
  • The InputManager.getOffsetY method has been removed as it's no longer required.
  • The InputManager.getScaleX method has been removed as it's no longer required.
  • The InputManager.getScaleY method has been removed as it's no longer required.
  • The SceneManager.resize method has been removed as it's no longer required.
  • The Scene.Systems.resize method has been removed as it's no longer required.
  • Scenes will no longer dispatch the resize event. You should now listen for this event from the Scale Manager instead.
  • BaseCamera.config has been removed as it's no longer required.
  • BaseCamera.scaleManager is a new property that references the Scale Manager and is used internally for size checks.
  • The Game.resize method has been removed as it's no longer required. You should now call ScaleManager.resize instead.
  • The Game will no longer dispatch the resize event. You should now listen for this event from the Scale Manager instead.

Important Namespace Changes

  • The Phaser.Boot namespace has been renamed to Phaser.Core. As a result, the boot folder has been renamed to core. This impacts the TimeStep class and VisibilityHandler function, which have been moved to be under the new namespace.
  • The Phaser.Animations namespace was incorrectly exposed in the Phaser entrypoints as Animation (note the lack of plural). This means that if you are creating any custom classes that extend Animation objects using the Phaser namespace, then please update them from Phaser.Animation to Phaser.Animations, i.e. Phaser.Animation.AnimationFrame to Phaser.Animations.AnimationFrame. This doesn't impact you if you created animations directly via the Animation Manager.
  • The keyed Data Manager change data event string has changed from changedata_ to changedata- to keep it consistent with other keyed events. Note the change from _ to -.
  • The Keyboard Plugin keydown dynamic event string has changed from keydown_ to keydown- to keep it consistent with other keyed events. Note the change from _ to -.
  • The Keyboard Plugin keyup dynamic event string has changed from keyup_ to keyup- to keep it consistent with other keyed events. Note the change from _ to -.
  • The texturesready event emitted by the Texture Manager has been renamed to ready.
  • The loadcomplete event emitted by the Loader Plugin has been renamed to postprocess to be reflect what it's used for.
  • Game Objects used to emit a collide event if they had an Arcade Physics Body with onCollide set, that collided with a Tile. This has changed. The event has been renamed to tilecollide and you should now listen for this event from the Arcade Physics World itself: this.physics.world.on('tilecollide'). Game Objects no longer emit this event.
  • Game Objects used to emit an overlap event if they had an Arcade Physics Body with onOverlap set, that overlapped with a Tile. This has changed. The event has been renamed to tileoverlap and you should now listen for this event from the Arcade Physics World itself: this.physics.world.on('tileoverlap'). Game Objects no longer emit this event.
  • The function Phaser.Physics.Impact.SeperateX has been renamed to SeparateX to correct the spelling mistake.
  • The function Phaser.Physics.Impact.SeperateY has been renamed to SeparateY to correct the spelling mistake.
  • The ended event in WebAudioSound has been renamed to complete to make it more consistent with the rest of the API.
  • The ended event in HTML5AudioSound has been renamed to complete to make it more consistent with the rest of the API.

New Features

  • You can now load external Scene files using the new load.sceneFile method. This allows you to dynamically load a Scene into the Scene Manager of your game, and swap to it at will. Please see the documentation and examples for further details.
  • The data object being sent to the Dynamic Bitmap Text callback now has a new property parent, which is a reference to the Bitmap Text instance that owns the data object (thanks ornyth)
  • The WebGL Renderer has a new method clearPipeline, which will clear down the current pipeline and reset the blend mode, ready for the context to be passed to a 3rd party library.
  • The WebGL Renderer has a new method rebindPipeline, which will rebind the given pipeline instance, reset the blank texture and reset the blend mode. This is useful for recovering from 3rd party libs that have modified the gl context.
  • Game Objects have a new property called state. Use this to track the state of a Game Object during its lifetime. For example, it could move from a state of 'moving', to 'attacking', to 'dead'. Phaser itself will never set this property, although plugins are allowed to.
  • Game Objects have a new method called setState which will set the state property in a chainable call.
  • BlendModes.ERASE is a new blend mode that will erase the object being drawn. When used in conjunction with a Render Texture it allows for effects that require you to erase parts of the texture, in either Canvas or WebGL. When used with a transparent game canvas, it allows you to erase parts of the canvas, showing the web page background through.
  • BlendModes.SOURCE_IN is a new Canvas-only blend mode that allows you to use the source-in composite operation when rendering Game Objects.
  • BlendModes.SOURCE_OUT is a new Canvas-only blend mode that allows you to use the source-out composite operation when rendering Game Objects.
  • BlendModes.SOURCE_ATOP is a new Canvas-only blend mode that allows you to use the source-atop composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_OVER is a new Canvas-only blend mode that allows you to use the destination-over composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_IN is a new Canvas-only blend mode that allows you to use the destination-in composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_OUT is a new Canvas-only blend mode that allows you to use the destination-out composite operation when rendering Game Objects.
  • BlendModes.DESTINATION_ATOP is a new Canvas-only blend mode that allows you to use the destination-atop composite operation when rendering Game Objects.
  • BlendModes.LIGHTER is a new Canvas-only blend mode that allows you to use the lighter composite operation when rendering Game Objects.
  • BlendModes.COPY is a new Canvas-only blend mode that allows you to use the copy composite operation when rendering Game Objects.
  • BlendModes.XOR is a new Canvas-only blend mode that allows you to use the xor composite operation when rendering Game Objects.
  • RenderTexture.erase is a new method that will take an object, or array of objects, and draw them to the Render Texture using an ERASE blend mode, resulting in them being removed from the Render Texture. This is really handy for making a bitmap masked texture in Canvas or WebGL (without using an actual mask), or for 'cutting away' part of a texture.
  • There is a new boolean Game Config property called customEnvironment. If set to true it will skip the internal Feature checks when working out which type of renderer to create, allowing you to run Phaser under non-native web environments. If using this value, you must set an explicit renderType of either CANVAS or WEBGL. It cannot be left as AUTO. Fix #4166 (thanks @jcyuan)
  • Animation.nextFrame will advance an animation to the next frame in the sequence instantly, regardless of the animation time or state. You can call this on a Sprite: sprite.anims.nextFrame() (thanks rgk25)
  • Animation.previousFrame will set an animation to the previous frame in the sequence instantly, regardless of the animation time or state. You can call this on a Sprite: sprite.anims.previousFrame() (thanks rgk25)
  • Geom.Intersects.PointToLine has a new optional argument lineThickness (which defaults to 1). This allows you to determine if the point intersects a line of a given thickness, where the line-ends are circular (not square).
  • Geom.Line.GetNearestPoint is a new static method that will return the nearest point on a line to the given point.
  • Geom.Line.GetShortestDistance is a new static method that will return the shortest distance from a line to the given point.
  • Camera.getBounds is a new method that will return a rectangle containing the bounds of the camera.
  • Camera.centerOnX will move the camera horizontally to be centered on the given coordinate without changing its vertical placement.
  • Camera.centerOnY will move the camera vertically to be centered on the given coordinate without changing its horizontally placement.
  • AnimationManager.exists is a new method that will check to see if an Animation using the given key already exists or not and returns a boolean.
  • animationstart-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationstart-explode.
  • animationrestart-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationrestart-explode.
  • animationcomplete-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationcomplete-explode.
  • animationupdate-key is a new Animation key specific event emitted by a Game Object. For example, if you had an animation with a key of 'explode' you can now listen for animationupdate-explode.
  • The Animation class now extends the Event Emitter and dispatches events itself. This allows you to listen for events from a specific Animation, rather than via a Game Object. This is handy, for example, if you had an explosion animation that you wanted to trigger a sound effect when it started. You can now listen for the events from the Animation object directly.
  • The Animation class now emits the start event when played (either forward, or in reverse) by any Game Object.
  • The Animation class now emits the restart event when it restarts playing on any Game Object.
  • The Animation class now emits the complete event when it finishes playing on any Game Object.
  • The Animation Component has a new method called chain which allows you to line-up another animation to start playing as soon as the current one stops, no matter how it stops (either by reaching its natural end, or directly by having stop called on it). 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 callback). 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.
  • CanvasTexture.drawFrame is a new method that allows you to draw a texture frame to the CanvasTexture based on the texture key and frame given.
  • CanvasTexture.getIndex is a new method that will take an x/y coordinate and return the Image Data index offset used to retrieve the pixel values.
  • CanvasTexture.getPixels is a new method that will take a region as an x/y and width/height and return all of the pixels in that region from the CanvasTexture.
  • CanvasTexture.setPixel is a new method that sets the given pixel in the CanvasTexture to the color and alpha values provided.
  • CanvasTexture.getData is a new method that will extract an ImageData block from the CanvasTexture from the region given.
  • CanvasTexture.putData is a new method that will put an ImageData block at the given coordinates in a CanvasTexture.
  • Line.Extend is a new static function that allows you extend the start and/or end points of a Line by the given amounts.
  • Vector2.LEFT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.RIGHT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.UP is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.DOWN is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector2.ONE is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.ZERO is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.LEFT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.RIGHT is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.UP is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.DOWN is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.FORWARD is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.BACK is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Vector3.ONE is a new constant that can be used in Vector comparison operations (thanks @Aedalus)
  • Geometery Mask has a new property called invertAlpha in WebGL, which works in the same way as the flag on the Bitmap Mask and allows you to invert the function of the stencil buffer, i.e. non-drawn shapes become invisible, and drawn shapes visible (thanks @tfelix)
  • The Arcade Physics Body has a new property maxSpeed which limits the vector length of the Body velocity. You can set it via the method setMaxSpeed and it is applied in the World.computeVelocity method (thanks @Edwin222 @rexrainbow)
  • WebGLRenderer.snapshotArea is a new method that allows you to grab an image of the given region of the canvas during the post-render step and have it sent to your defined callback. This is the same as snapshot except you control the area being grabbed, so is more efficient if you only need a smaller area.
  • WebGLRenderer.snapshotPixel is a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as a Color object to your specified callback.
  • CanvasRenderer.snapshotArea is a new method that allows you to grab an image of the given region of the canvas during the post-render step and have it sent to your defined callback. This is the same as snapshot except you control the area being grabbed, so is more efficient if you only need a smaller area.
  • CanvasRenderer.snapshotPixel is a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as a Color object to your specified callback.

Updates

  • You can now modify this.physics.world.debugGraphic.defaultStrokeWidth to set the stroke width of any debug drawn body, previously it was always 1 (thanks @samme)
  • TextStyle.setFont has a new optional argument updateText which will sets if the text should be automatically updated or not (thanks @DotTheGreat)
  • ProcessQueue.destroy now sets the internal toProcess counter to zero.
  • The PathFollower.pathRotationVerticalAdjust property has been removed. It was supposed to flipY a follower when it reversed path direction, but after some testing it appears it has never worked and it's easier to do this using events, so the property and associated config value are removed. The verticalAdjust argument from the setRotateToPath method has been removed as well.
  • The config value preserveDrawingBuffer has been removed as it has never been used by the WebGL Renderer.
  • PluginManager.install returns null if the plugin failed to install in all cases.
  • PluginFile will now install the plugin into the current Scene as long as the start or mapping arguments are provided.
  • MATH_CONST no longer requires or sets the Random Data Generator, this is now done in the Game Config, allowing you to require the math constants without pulling in a whole copy of the RNG with it.
  • The Dynamic Bitmap Text Canvas Renderer was creating a new data object every frame for the callback. It now uses the callbackData object instead, like the WebGL renderer does.
  • WebGLRenderer.setBlendMode has a new optional argument force, which will force the given blend mode to be set, regardless of the current settings.
  • The method DisplayList.sortGameObjects has been removed. It has thrown a runtime error since v3.3.0(!) which no-one even spotted which is a good indication of how little the method was used. The display list is automatically sorted anyway, so if you need to sort a small section of it, just use the standard JavaScript Array sort method (thanks ornyth)
  • The method DisplayList.getTopGameObject has been removed. It has thrown a runtime error since v3.3.0(!) which no-one even spotted which is a good indication of how little the method was used (thanks ornyth)
  • WebGLRenderer.setFramebuffer has a new optional boolean argument updateScissor, which will reset the scissor to match the framebuffer size, or clear it.
  • WebAudioSoundManager.onFocus will not try to resume the Audio Context if it's still locked.
  • WebAudioSoundManager.onBlur will not try to suspend the Audio Context if it's still locked.
  • When using ScenePlugin.add, to add a new Scene to the Scene Manager, it didn't allow you to include the optional Scene data object. You can now pass this in the call (thanks @kainage)
  • Graphics.stroke is a new alias for the strokePath method, to keep the calls consistent with the Canvas Rendering Context API.
  • Graphics.fill is a new alias for the fillPath method, to keep the calls consistent with the Canvas Rendering Context API.
  • LoaderPlugin.sceneManager is a new property that is a reference to the global Scene Manager, useful for Plugins.
  • Whenever Camera.roundPixels was enabled it would use a bitwise operation to truncate the float (x |= 0) - this has been replaced across all files that used it, with a call to Math.round instead. This gives far better results when zooming cameras both in and out of a Scene, stopping thin gaps appearing between closely packed Game Objects.
  • AnimationManager.create will now return a boolean false if the given key is invalid (i.e. undefined or falsey).
  • AnimationManager.create will no longer raise a console warning if the animation key is already in use. Instead, it will return the animation belonging to that key. A brand new animation will only be created if the key isn't already in use. When this happens, the add event is emitted by the Animation Manager. If no event is emitted, the animation already existed.
  • ArcadePhysics.Body.destroy will now only add itself to the World pendingDestroy list if the world property exists. This prevents Cannot read property 'pendingDestroy' of undefined errors if you try to delete a physics body in a callback and then immediately change Scene (which tells the physics work to also delete all bodies)
  • The Animation Component restart method has had is sole key argument removed. Previously, you had to pass in the key of the animation you wished to reverse, but now you can just call the method directly, and as long as there is an animation playing, it will automatically start playing in reverse, without the nee for a key (the way it should have been originally)
  • Animation.play and playReverse will now accept either a string-based key of the animation to play (like before), or you can pass in an Animation instance, and it will play that animation.
  • CanvasTexture.clear now has 4 new optional arguments: x, y, width, height which allow you to define the region of the texture to be cleared. If not provided it will clear the whole texture, which is the same behavior as before.
  • EarCut, the polygon triangulation library used by the Graphics and WebGL classes, has been upgraded from 2.1.1 to 2.1.4. 2.1.2 fixed a few race conditions where bad input would cause an error. 2.1.3 improved performance for bigger inputs (5-12%) and 2.1.4 fixed a race condition that could lead to a freeze on degenerate input.
  • TextureTintPipeline.batchQuad and batchTri have two new optional arguments texture and unit which are used to re-set the batch texture should the method cause a batch flush.
  • TextureTintPipeline.requireTextureBatch is a new internal method that helps speed-up the creation of texture batches. It is used in conjunction with setTexture2D and pushBatch.
  • TextureTintPipeline.flush and TextureTintPipeline.pushBatch have been optimized to handle zero based texture units as priority. They've also been refactored to avoid creation of empty texture batches.
  • The WebGLRenderer.setTexture2D method has a new optional argument flush which controls if the pipeline is flushed if the given texture is new, or not. This is used internally to skip flushing during an existing flush.
  • The Tilemap Layer width and height properties are now based on the tilemap tile sizes multiplied by the layer dimensions. This corrects an issue with layer sizes being wrong if you called setBaseTileSize on a Map.
  • The WebGLRenderer will now clear the framebuffer at the start of every render.
  • WebGLRenderer.setScissor now has a new optional argument drawingBufferHeight which allows you to specify the drawing buffer height, rather than use the renderers default value.
  • WebGLRenderer.pushScissor now has a new optional argument drawingBufferHeight which allows you to specify the drawing buffer height, rather than use the renderers default value.
  • WebGLRenderer.preRender now calls gl.clearColor in order to restore the background clear color in case something, like a Render Texture, has changed it.
  • Map.set will now update an existing value if you provide it with a key that already exists within the Map. Previously, if you tried to set the value of a key that existed it would be skipped.
  • MatterSprite would set its type property to be Image. It now sets it to be Sprite as it should do.
  • Matter.TileBody.setFromTileCollision no longer checks if the shape is concave or convex before modifying the vertices, as the update to the Matter.js lib in 3.12 stopped this from working with Tiled collision shapes.
  • The Scene transitionstart event is now dispatched by the Target Scene of a transition, regardless if the Scene has a create method or not. Previously, it was only dispatched if the Scene had a create method.
  • The Loader will now allow an XHR status of 0 as success too. Normally only status 200 would be accepted as success, but 0 is returned when a file is loaded from the local filesystem (file://). This happens, for example, when opening the index.html of a game in a browser directly, or when using Cordova on iOS. Fix #3464 (thanks @Ithamar)
  • Tween.restart now returns the Tween instance (thanks @rexrainbow)
  • Tween.play now returns the Tween instance (thanks @rexrainbow)
  • Tween.seek now returns the Tween instance (thanks @rexrainbow)
  • Tween.complete now returns the Tween instance (thanks @rexrainbow)
  • Tween.stop now returns the Tween instance (thanks @rexrainbow)
  • List.sort now has an optional parameter handler which allows you to provide your own sort handling function (thanks @jcyuan)
  • Container.sort now has an optional parameter handler which allows you to provide your own sort handling function (thanks @jcyuan)
  • The WebGLRenderer method canvasToTexture will now only set the filter to be NEAREST if antialias is disabled in the game config (i.e. when running in pixelArt mode). This means that Text objects, and other Canvas backed textures, now render with anti-aliasing if everything else does. You can disable this on a per-object basis by calling texture.setFilter(1) on them.
  • CanvasRenderer.snapshotCallback, snapshotType and snapshotEncoder have all been removed as they are no longer required.
  • CanvasRenderer.snapshotState is a new object that contains the snapshot configuration data, the same as the WebGL Renderer.
  • The signature of the WebGLSnapshot function has changed. It now takes a Snapshot Configuration object as the second parameter.
  • The signature of the CanvasSnapshot function has changed. It now takes a Snapshot Configuration object as the second parameter.

Bug Fixes

  • The Rectangle Shape object wouldn't render if it didn't have a stroke, or any other objects on the display list (thanks mliko)
  • When using a font string instead of setting fontFamily, fontSize and fontStyle in either Text.setStyle or setFont, the style properties wouldn't get set. This isn't a problem while creating the text object, only if modifying it later (thanks @DotTheGreat)
  • Text.toJSON wasn't saving the font style when using the "font" shorthand to create it. It now saves it correctly. Fix #4141 (thanks @divillysausages)
  • Disabling camera bounds and then moving the camera to an area in a Tilemap that did not have any tile information would throw an Uncaught Reference error as it tried to access tiles that did not exist (thanks @Siyalatas)
  • Fixed an issue where Sprite Sheets being extracted from a texture atlas would fail if the sheet was either just a single column or single row of sprites. Fix #4096 (thanks @Cirras)
  • If you created an Arcade Physics Group without passing a configuration object, and passing an array of non-standard children, it would throw a classType runtime error. It now creates a default config object correctly (thanks @pierpo)
  • The Camera.cull method has been restructured so it now calculates if a Game Object is correctly in view or not before culling it. Although not used internally, if you need to cull objects for a camera, you can now safely use this method. Fix #4092 (thanks @Cirras)
  • The Tiled Parser would ignore animated tile data if it was in the new Tiled 1.2 format. This is now accounted for, as well as 1.0 (thanks @nkholski)
  • Array.Matrix.ReverseRows was actually reversing the columns, but now reverses the rows.
  • Array.Matrix.ReverseColumns was actually reversing the rows, but now reverses the columns.
  • UnityAtlas now sets the correct file type key if using a config file object.
  • Starting with version 3.13 in the Canvas Renderer, it was possible for long-running scripts to start to get bogged-down in fillRect calls if the game had a background color set. The context is now saved properly to avoid this. Fix #4056 (thanks @Aveyder)
  • Render Textures created larger than the size of the default canvas would be automatically clipped when drawn to in WebGL. They now reset the gl scissor and drawing height property in order to draw to their full size, regardless of the canvas size. Fix #4139 (thanks @chaoyang805 @iamchristopher)
  • The cameraFilter property of a Game Object will now allow full bitmasks to be set (a value of -1), instead of just those > 0 (thanks @stuartkeith)
  • The PathFollower.startFollow method now properly uses the startAt argument to the method, so you can start a follower off at any point along the path. Fix #3688 (thanks @DannyT @diteix)
  • Static Circular Arcade Physics Bodies now render as circles in the debug display instead of showing their rectangle bounds (thanks @maikthomas)
  • Changing the mute flag on an HTML5AudioSound instance, via the mute setter, now works as it does via the Sound Manager (thanks @Waclaw-I @neon-dev)
  • Changing the volume on an HTML5AudioSound instance, via the volume setter, now works as it does via the Sound Manager (thanks @Waclaw-I)
  • The Dynamic Tilemap Layer WebGL renderer was drawing tiles at the incorrect position if the layer was scaled. Fix #4104 (thanks @the-realest-stu)
  • Tile.tileset now returns the specific Tileset associated with the tile rather than an array of them. Fix #4095 (thanks @quadrupleslap)
  • Tile.getCollisionGroup wouldn't return the correct Group after the change to support multiple Tilesets. It now returns the group properly (thanks @jbpuryear)
  • Tile.getTileData wouldn't return the correct data after the change to support multiple Tilesets. It now returns the tile data properly (thanks @jbpuryear)
  • The GetTileAt and RemoveTileAt components would error with "Cannot read property 'index' of undefined" if the tile was undefined rather than null. It now handles both cases (thanks @WaSa42)
  • Changing TileSprite.width or TileSprite.height will now flag the texture as dirty and call updateDisplayOrigin, allowing you to resize TileSprites dynamically in both Canvas and WebGL.
  • RandomDataGenerator.shuffle has been fixed to use the proper modifier in the calculation allowing for a more even distribution (thanks wayfinder)
  • The Particle Emitter was not recycling dead particles correctly so it was creating new objects every time it emitted (the old particles were then left to the browsers gc to clear up). This has now been recoded so the emitter will properly keep track of dead particles and re-use them (thanks @Waclaw-I for the initial PR)
  • ParticleEmitter.indexSortCallback has been removed as it's no longer required.
  • Particle.index has been removed as it's no longer required. Particles don't need to keep track of their index any more.
  • The Particle Emitter no longer needs to call the StableSort.inplace during its preUpdate, saving cpu.
  • Particle.resetPosition is a new method that is called when a particle dies preparing it for firing again in the future.
  • The Canvas SetTransform method would save the context state, but it wasn't restored at the end in the following Game Objects: Dynamic Bitmap Text, Graphics, Arc, Curve, Ellipse, Grid, IsoBox, IsoTriangle, Line, Polygon, Rectangle, Star and Triangle. These now all restore the context, meaning if you're using non-canvas sized cameras in Canvas mode, it will now render beyond just the first custom camera.
  • Utils.Array.MoveUp wouldn't let you move an array element to the top-most index in the array. This also impacted Container.moveUp.
  • The Texture Tint Pipeline had a logic error that would cause every 2001st quad to either be invisible, or pick-up the texture of the 2000th quad by mistake. The batchQuad and batchTri methods how handle re-assigning the batch texture if they cause a batch flush as part of their process.
  • Rotating Sprites that used a Normal Map wouldn't rotate the normal map with it causing the lighting effects to become irregular. The normal map vectors are now rotated correctly (thanks @sercant for the PR and @fazzamatazz and @ysraelJMM for the report)
  • Changing scaleX or scaleY on a MatterImage or MatterSprite would cause the body scale to become distorted as the setters didn't use the correct factor when resetting the initial scale. Fix #4206 (thanks @YannCaron)
  • StaticBody.reset in Arcade Physics would ignore the x and y values given to it. If given, they're now used to reset the parent Game Object before the body is updated. Fix #4224 (thanks @samme)
  • Static Tilemap Layers wouldn't render correctly if the layer used a tileset with a different size to the base map data (set via setBaseTileSize). They now render correctly in WebGL and Canvas regardless of the base tile size.
  • When using RenderTexture.fill, the alpha argument would be ignored in Canvas mode. It's now used when filling the RenderTexture.
  • Fixed an issue in WebGLRenderer.setScissor where it was possible to try and compare the scissor size to a non-current scissor if called outside of the render loop (i.e. from RenderTexture.fill) (thanks @hackhat)
  • RenderTexture.fill in WebGL would use gl.clear and a clear color to try and fill the Render Texture. This only worked for full-canvas sized RenderTextures that didn't have a camera zoom applied. It has now been swapped to use the drawFillRect method of the Texture Tint Pipeline, allowing it to work properly regardless of camera zoom or size.
  • Container.getFirst was using an incorrect Array Utils function GetFirstElement when it should have been using GetFirst. It now uses the correct function. Fix #4244 (thanks @miran248)
  • List.getFirst was using an incorrect Array Utils function GetFirstElement when it should have been using GetFirst. It now uses the correct function. Fix #4244 (thanks @miran248)
  • Fixed an issue where changing the viewport or size of a Camera belonging to a RenderTexture wouldn't impact the rendering and objects will still render outside of the viewport range. It's now converted to a proper gl scissor rect by the renderer, meaning you can limit the area rendered to by adjusting the internal Render Texture cameras viewport. Fix #4243 (thanks @hackhat)
  • CanvasTexture.destroy is a new method that specifically handles the destruction of the CanvasTexture and all of its associated typed arrays. This prevents a memory leak when creating and destroying lots of RenderTextures (which are CanvasTexture backed). Fix #4239 (thanks @sjb933)
  • The Alpha, Flip and Origin components have been removed from the Mesh Game Object (and by extension, Quad as well) as they are not used in the renderer and should be manipulated via the Mesh properties. Fix #4188 (thanks @enriqueto)
  • The processDomCallbacks method in the Input Manager wasn't correctly clearing the once arrays. Responsibility for this has now been passed to the queue methods queueTouchStart, queueTouchMove, queueTouchEnd, queueMouseDown, queueMouseMove and queueMouseUp. Fix #4257 (thanks @iArePJ)
  • Arcade Physics now manages when postUpdate should be applied better, stopping it from gaining a zero delta during a further check in the same frame. This fixes various issues, including the mass collision test demo. Fix #4154 (thanks @samme)
  • Arcade Physics could trigger a collide event on a Body even if it performing an overlap check, if the onCollide property was true (thanks @samme)
  • TileSprites no longer cause a crash when using the Headless mode renderer. Fix #4297 (thanks @clesquir)
  • The WebGLRenderer will now apply a transparent background if transparent = true in the game config (thanks @gomachan7)
  • List.sort was missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)
  • Container.sort was missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)
  • DataManager.pop would emit the DataManager instance, instead of the parent, as the first event argument. It now emits the parent as it should do. Fix #4186 (thanks @gadelan)

Examples and TypeScript

Thanks to the following for helping with the Phaser 3 Examples and TypeScript definitions, either by reporting errors, or even better, fixing them:

@guilhermehto @samvieten @darkwebdev @RoryO @snowbillr @slothyrulez @jcyuan @jestarray

Phaser Doc Jam

The Phaser Doc Jam was a community-backed effort to try and get the Phaser 3 API documentation to 100% coverage. The Doc Jam is now over and I offer my thanks to the following who helped with docs in this release:

@16patsle - @gurungrahul2 - @icbat - @samme - @telinc1 - anandu pavanan - blackhawx - candelibas - Diego Romero - doronlinder - Elliott Wallace - eric - Georges Gabereau - Haobo Zhang - henriacle - jak6jak - Jake Jensen - James Van Roose - JamesSkemp - joelahoover - Joey - madclaws - marc136 - Mihail Ilinov - naum303 - NicolasRoehm - nuane - rejacobson - Robert Kowalski - rodri042 - rootasjey - sawamara - scottwestover - sir13tommy - stetso - therealsamf - Tigran - willblackmore - zenwaichi

Also, the following helped with the docs outside of the Doc Jam:

@bryanwood @jestarray @matosummer @tfelix @imilo @BigZaphod @OmarShehata @16patsle @jcyuan @iam13islucky @FractalBobz

- JavaScript
Published by photonstorm over 7 years ago

phaser - Phaser v3.15.1 Release

Version 3.15.1 - Batou - 16th October 2018

  • Re-enabled Input Manager resizing, which had been left disabled by mistake.

Version 3.15.0 - Batou - 16th October 2018

Note: We are releasing this version ahead of schedule in order to make some very important iOS performance and input related fixes available. It does not contain the new Scale Manager or Spine support, both of which have been moved to 3.16 as they require a few more weeks of development.

New Features

  • You can now set the maxLights value in the Game Config, which controls the total number of lights the Light2D shader can render in a single pass. The default is 10. Be careful about pushing this too far. More lights = less performance. Close #4081 (thanks @FrancescoNegri)
  • Rectangle.SameDimensions determines if the two objects (either Rectangles or Rectangle-like) have the same width and height values under strict equality.
  • An ArcadePhysics Group can now pass { enable: false }` in its config to disable all the member bodies (thanks @samme)
  • Body.setEnable is a new chainable method that allows you to toggle the enable state of an Arcade Physics Body (thanks @samme)
  • KeyboardPlugin.resetKeys is a new method that will reset the state of any Key object created by a Scene's Keyboard Plugin.
  • Pointer.wasCanceled is a new boolean property that allows you to tell if a Pointer was cleared due to a touchcancel event. This flag is reset during the next touchstart event for the Pointer.
  • Pointer.touchcancel is a new internal method specifically for handling touch cancel events. It has the same result as touchend without setting any of the up properties, to avoid triggering up event handlers. It will also set the wasCanceled property to true.

Updates

  • WebGLRenderer.deleteTexture will check to see if the texture it is being asked to delete is the currently bound texture or not. If it is, it'll set the blank texture to be bound after deletion. This should stop RENDER WARNING: there is no texture bound to the unit 0 errors if you destroy a Game Object, such as Text or TileSprite, from an async or timed process (thanks jamespierce)
  • The RequestAnimationFrame.step and stepTimeout functions have been updated so that the new Frame is requested from raf before the main game step is called. This allows you to now stop the raf callback from within the game update or render loop. Fix #3952 (thanks @tolimeh)
  • If you pass zero as the width or height when creating a TileSprite it will now use the dimensions of the texture frame as the size of the TileSprite. Fix #4073 (thanks @jcyuan)
  • TileSprite.setFrame has had both the updateSize and updateOrigin arguments removed as they didn't do anything for TileSprites and were misleading.
  • CameraManager.remove has a new argument runDestroy which, if set, will automatically call Camera.destroy on the Cameras removed from the Camera Manager. You should nearly always allow this to happen (thanks jamespierce)
  • Device.OS has been restructured to allow fake UAs from Chrome dev tools to register iOS devices.
  • Texture batching during the batch flush has been implemented in the TextureTintPipeline which resolves the issues of very low frame rates, especially on iOS devices, when using non-batched textures such as those used by Text or TileSprites. Fix #4110 #4086 (thanks @ivanpopelyshev @sachinhosmani @maximtsai @alexeymolchan)
  • The WebGLRenderer method canvasToTexture has a new optional argument noRepeat which will stop it from using gl.REPEAT entirely. This is now used by the Text object to avoid it potentially switching between a REPEAT and CLAMP texture, causing texture black-outs (thanks @ivanpopelyshev)
  • KeyboardPlugin.resetKeys is now called automatically as part of the Keyboard Plugin shutdown method. This means, when the plugin shuts down, such as when stopping a Scene, it will reset the state of any key held in the plugin. It will also clear the queue of any pending events.
  • The Touch Manager has been rewritten to use declared functions for all touch event handlers, rather than bound functions. This means they will now clear properly when the TouchManager is shut down.
  • There is a new Input constant TOUCH_CANCEL which represents canceled touch events.

Bug Fixes

  • Fixed a bug in the canvas rendering of both the Static and Dynamic Tilemap Layers where the camera matrix was being multiplied twice with the layer, causing the scale and placement to be off (thanks galerijanamar)
  • If you set pixelArt to true in your game config (or antialias to false) then TileSprites will now respect this when using the Canvas Renderer and disable smoothing on the internal fill canvas.
  • TileSprites that were set to be interactive before they had rendered once wouldn't receive a valid input hit area, causing input to fail. They now define their size immediately, allowing them to be made interactive without having rendered. Fix #4085 (thanks @DotTheGreat)
  • The Particle Emitter Manager has been given a NOOP method called setBlendMode to stop warnings from being thrown if you added an emitter to a Container in the Canvas renderer. Fix #4083 (thanks @maximtsai)
  • The game.context property would be incorrectly set to null after the WebGLRenderer instance was created (thanks @samme)
  • The Touch Manager, Input Manager and Pointer classes all now handle the touchcancel event, such as triggered on iOS when activating an out of browser UI gesture, or in Facebook Instant Games when displaying an overlay ad. This should prevent issues with touch input becoming locked on iOS specifically. Fix #3756 (thanks @sftsk @sachinhosmani @kooappsdevs)

- JavaScript
Published by photonstorm over 7 years ago

phaser - Phaser v3.15.0 Release

Version 3.15.0 - Batou - 16th October 2018

Note: We are releasing this version ahead of schedule in order to make some very important iOS performance and input related fixes available. It does not contain the new Scale Manager or Spine support, both of which have been moved to 3.16 as they require a few more weeks of development.

New Features

  • You can now set the maxLights value in the Game Config, which controls the total number of lights the Light2D shader can render in a single pass. The default is 10. Be careful about pushing this too far. More lights = less performance. Close #4081 (thanks @FrancescoNegri)
  • Rectangle.SameDimensions determines if the two objects (either Rectangles or Rectangle-like) have the same width and height values under strict equality.
  • An ArcadePhysics Group can now pass { enable: false }` in its config to disable all the member bodies (thanks @samme)
  • Body.setEnable is a new chainable method that allows you to toggle the enable state of an Arcade Physics Body (thanks @samme)
  • KeyboardPlugin.resetKeys is a new method that will reset the state of any Key object created by a Scene's Keyboard Plugin.
  • Pointer.wasCanceled is a new boolean property that allows you to tell if a Pointer was cleared due to a touchcancel event. This flag is reset during the next touchstart event for the Pointer.
  • Pointer.touchcancel is a new internal method specifically for handling touch cancel events. It has the same result as touchend without setting any of the up properties, to avoid triggering up event handlers. It will also set the wasCanceled property to true.

Updates

  • WebGLRenderer.deleteTexture will check to see if the texture it is being asked to delete is the currently bound texture or not. If it is, it'll set the blank texture to be bound after deletion. This should stop RENDER WARNING: there is no texture bound to the unit 0 errors if you destroy a Game Object, such as Text or TileSprite, from an async or timed process (thanks jamespierce)
  • The RequestAnimationFrame.step and stepTimeout functions have been updated so that the new Frame is requested from raf before the main game step is called. This allows you to now stop the raf callback from within the game update or render loop. Fix #3952 (thanks @tolimeh)
  • If you pass zero as the width or height when creating a TileSprite it will now use the dimensions of the texture frame as the size of the TileSprite. Fix #4073 (thanks @jcyuan)
  • TileSprite.setFrame has had both the updateSize and updateOrigin arguments removed as they didn't do anything for TileSprites and were misleading.
  • CameraManager.remove has a new argument runDestroy which, if set, will automatically call Camera.destroy on the Cameras removed from the Camera Manager. You should nearly always allow this to happen (thanks jamespierce)
  • Device.OS has been restructured to allow fake UAs from Chrome dev tools to register iOS devices.
  • Texture batching during the batch flush has been implemented in the TextureTintPipeline which resolves the issues of very low frame rates, especially on iOS devices, when using non-batched textures such as those used by Text or TileSprites. Fix #4110 #4086 (thanks @ivanpopelyshev @sachinhosmani @maximtsai @alexeymolchan)
  • The WebGLRenderer method canvasToTexture has a new optional argument noRepeat which will stop it from using gl.REPEAT entirely. This is now used by the Text object to avoid it potentially switching between a REPEAT and CLAMP texture, causing texture black-outs (thanks @ivanpopelyshev)
  • KeyboardPlugin.resetKeys is now called automatically as part of the Keyboard Plugin shutdown method. This means, when the plugin shuts down, such as when stopping a Scene, it will reset the state of any key held in the plugin. It will also clear the queue of any pending events.
  • The Touch Manager has been rewritten to use declared functions for all touch event handlers, rather than bound functions. This means they will now clear properly when the TouchManager is shut down.
  • There is a new Input constant TOUCH_CANCEL which represents canceled touch events.

Bug Fixes

  • Fixed a bug in the canvas rendering of both the Static and Dynamic Tilemap Layers where the camera matrix was being multiplied twice with the layer, causing the scale and placement to be off (thanks galerijanamar)
  • If you set pixelArt to true in your game config (or antialias to false) then TileSprites will now respect this when using the Canvas Renderer and disable smoothing on the internal fill canvas.
  • TileSprites that were set to be interactive before they had rendered once wouldn't receive a valid input hit area, causing input to fail. They now define their size immediately, allowing them to be made interactive without having rendered. Fix #4085 (thanks @DotTheGreat)
  • The Particle Emitter Manager has been given a NOOP method called setBlendMode to stop warnings from being thrown if you added an emitter to a Container in the Canvas renderer. Fix #4083 (thanks @maximtsai)
  • The game.context property would be incorrectly set to null after the WebGLRenderer instance was created (thanks @samme)
  • The Touch Manager, Input Manager and Pointer classes all now handle the touchcancel event, such as triggered on iOS when activating an out of browser UI gesture, or in Facebook Instant Games when displaying an overlay ad. This should prevent issues with touch input becoming locked on iOS specifically. Fix #3756 (thanks @sftsk @sachinhosmani @kooappsdevs)

- JavaScript
Published by photonstorm over 7 years ago

phaser - Phaser v3.14.0 Release

Version 3.14.0 - Tachikoma - 1st October 2018

Tilemap New Features, Updates and Fixes

  • Both Static and Dynamic Tilemap layers now support rendering multiple tilesets per layer in both Canvas and WebGL. To use multiple tilesets pass in an array of Tileset objects, or strings, to the createStaticLayer and createDynamicLayer methods respectively.
  • Tilemap.createStaticLayer now supports passing either a Tileset reference, or a string, or an array of them as the 2nd argument. If strings, the string should be the Tileset name (usually defined in Tiled).
  • Tilemap.createDynamicLayer now supports passing either a Tileset reference, or a string, or an array of them as the 2nd argument. If strings, the string should be the Tileset name (usually defined in Tiled).
  • Tilemap.createBlankDynamicLayer now supports passing either a Tileset reference, or a string, or an array of them as the 2nd argument. If strings, the string should be the Tileset name (usually defined in Tiled).
  • Static Tilemap Layers now support tile rotation and flipping. Previously this was a feature only for Dynamic Tilemap Layers, but now both have it. Close #4037 (thanks @thisredone)
  • Tilemap.getTileset is a new method that will return a Tileset based on its name.
  • ParseTilesets has been rewritten so it will convert the new data structures of Tiled 1.2 into the format expected by Phaser, allowing you to use either Tiled 1.2.x or Tiled 1.1 JSON exports. Fix #3998 (thanks @martin-pabst @halgorithm)
  • Tilemap.setBaseTileSize now sets the size into the LayerData baseTileWidth and baseTileHeight properties accordingly. Fix #4057 (thanks @imilo)
  • Calling Tilemap.renderDebug ignored the layer world position when drawing to the Graphics object. It will now translate to the layer position before drawing. Fix #4061 (thanks @Zax37)
  • Calling Tilemap.renderDebug ignored the layer scale when drawing to the Graphics object. It will now scale the layer before drawing. Fix #4026 (thanks @JasonHK)
  • The Static Tilemap Layer would stop drawing all tiles from that point on, if it encountered a tile which had invalid texture coordinates (such as a tile from another tileset). It now skips invalid tiles properly again. Fix #4002 (thanks @jdotrjs)
  • If you used a RenderTexture as a tileset then Dynamic Tilemap Layers would render the tiles inversed on the y-axis in WebGL. Fix #4017 (thanks @s-s)
  • If you used a scaled Dynamic Tilemap Layer and rotated or flipped tiles, the tiles that were rotated or flipped would be positioned incorrectly in WebGL. Fix #3778 (thanks @nkholski)
  • StaticTilemapLayer.tileset is now an array of Tileset objects, where-as before it was a single reference.
  • StaticTilemapLayer.vertexBuffer is now an array of WebGLBuffer objects, where-as before it was a single instance.
  • StaticTilemapLayer.bufferData is now an array of ArrayBuffer objects, where-as before it was a single instance.
  • StaticTilemapLayer.vertexViewF32 is now an array of Float3Array objects, where-as before it was a single instance.
  • StaticTilemapLayer.vertexViewU32 is now an array of Uint32Array objects, where-as before it was a single instance.
  • StaticTilemapLayer.dirty is now an array of booleans, where-as before it was a single boolean.
  • StaticTilemapLayer.vertextCount is now an array of integers, where-as before it was a single integer.
  • StaticTilemapLayer.updateVBOData() is a new private method that creates the internal VBO data arrays for the WebGL renderer.
  • The StaticTilemapLayer.upload() method has a new parameter tilesetIndex which controls which tileset to prepare the VBO data for.
  • The StaticTilemapLayer.batchTile() method has a new parameter tilesetIndex which controls which tileset to batch the tile for.
  • StaticTilemapLayer.setTilesets() is a new private method that creates the internal tileset references array.
  • DynamicTilemapLayer.tileset is now an array of Tileset objects, where-as before it was a single reference.
  • DynamicTilemapLayer.setTilesets() is a new private method that creates the internal tileset references array.

New Features

  • bodyDebugFillColor is a new Matter Physics debug option that allows you to set a color used when drawing filled bodies to the debug Graphic.
  • debugWireframes is a new Matter Physics debug option that allows you to control if the wireframes of the bodies are used when drawing to the debug Graphic. The default is true. If enabled bodies are not filled.
  • debugShowInternalEdges is a new Matter Physics debug option that allows you to set if the internal edges of a body are rendered to the debug Graphic.
  • debugShowConvexHulls is a new Matter Physics debug option that allows you to control if the convex hull of a body is drawn to the debug Graphic. The default is false.
  • debugConvexHullColor is a new Matter Physics debug option that lets you set the color of the convex hull, if being drawn to the debug Graphic.
  • debugShowSleeping is a new Matter Physics debug option that lets you draw sleeping bodies at 50% opacity.
  • Curves.Ellipse.angle is a new getter / setter that handles the rotation of the curve in degrees instead of radians.

Updates

  • The Loader has been updated to handle the impact of you destroying the game instance while still processing files. It will no longer throw cache and texture related errors. Fix #4049 (thanks @pantoninho)
  • Polygon.setTo can now take a string of space separated numbers when creating the polygon data, i.e.: '40 0 40 20 100 20 100 80 40 80 40 100 0 50'. This update also impacts the Polygon Shape object, which can now also take this format as well.
  • The poly-decomp library, as used by Matter.js, has been updated to 0.3.0.
  • Matter.verts, available via this.matter.verts from within a Scene, is a quick way of accessing the Matter Vertices functions.
  • You can now specify the vertices for a Matter fromVerts body as a string.
  • TextureTintPipeline.batchTexture has a new optional argument skipFlip which allows you to control the internal render texture flip Y check.
  • The Device.OS check for node will now do a typeof first to avoid issues with rollup packaged builds needing to shim the variable out. Fix #4058 (thanks @hollowdoor)
  • Arcade Physics Bodies will now sync the display origin of the parent Game Object to the body properties as part of the updateBounds call. This means if you change the origin of an AP enabled Game Object, after creation of the body, it will be reflected in the body position. This may or may not be a breaking change for your game. Previously it was expected that the origin should always be 0.5 and you adjust the body using setOffset, but this change makes a bit more sense logically. If you find that your bodies are offset after upgrading to this version then this is likely why. Close #4052 (thanks @SolarOmni)
  • The Texture.getFramesFromTextureSource method has a new boolean argument includeBase, which defaults to false and allows you to set if the base frame should be returned into the array or not.
  • There is a new Animation Event that is dispatched when an animation restarts. Listen for it via Sprite.on('animationrestart').
  • All of the Animation Events now pass the Game Object as the final argument, this includes animationstart, animationrestart, animationrepeat, animationupdate and animationcomplete.
  • Curves.Ellipse.rotation is a getter / setter that holds the rotation of the curve. Previously it expected the value in degrees and when getting it returned the value in radians. It now expects the value in radians and returns radians to keep it logical.
  • Set.size will now only set the new size if the value is smaller than the current size, truncating the Set in the process. Values larger than the current size are ignored.
  • Arcade Physics shutdown will check to see if the world instance still exists and only try removing it if so. This prevents errors when stopping a world and then destroying it at a later date.
  • Text.setFont, Text.setFontFamily, Text.setFontStyle and Text.setStroke will no longer re-measure the parent Text object if their values have not changed.

Bug Fixes

  • GameObjects added to and removed from Containers no longer listen for the shutdown event at all (thanks Vitali)
  • Sprites now have preDestroy method, which is called automatically by destroy. The method destroys the Animation component, unregistering the remove event in the process and freeing-up resources. Fix #4051 (thanks @Aveyder)
  • UpdateList.shutdown wasn't correctly iterating over the pending lists (thanks @felipeprov)
  • Input detection was known to be broken when the game resolution was !== 1 and the Camera zoom level was !== 1. Fix #4010 (thanks @s-s)
  • The Shape.Line object was missing a lineWidth property unless you called the setLineWidth method, causing the line to not render in Canvas only. Fix #4068 (thanks @netgfx)
  • All parts of Matter Body now have the gameObject property set correctly. Previously only the first part of the Body did.
  • When using MatterGameObject and fromVerts as the shape type it wouldn't pass the values to Bodies.fromVertices because of a previous conditional. It now passes them over correctly and the body is only set if the result is valid.
  • The Texture.getFramesFromTextureSource method was returning an array of Frame names by mistake, instead of Frame references. It now returns the Frames themselves.
  • When using CanvasTexture.refresh or Graphics.generateTexture it would throw WebGL warnings like 'bindTexture: Attempt to bind a deleted texture'. This was due to the Frames losing sync with the glTexture reference used by their TextureSource. Fix #4050 (thanks @kanthi0802)
  • Fixed an error in the batchSprite methods in the Canvas and WebGL Renderers that would incorrectly set the frame dimensions on Sprites with the crop component. This was particularly noticeable on Sprites with trimmed animation frames (thanks @sergeod9)
  • Fixed a bug where the gl scissor wasn't being reset during a renderer resize, causing it to appear as if the canvas didn't resize properly when autoResize was set to true in the game config. Fix #4066 (thanks @Quinten @hsan999)
  • If a Game instance is destroyed without using the removeCanvas argument, it would throw exceptions in the MouseManager after the destroy process has run, as the event listeners were not unbound. They're not unbound, regardless of if the parent canvas is removed or not. Fix #4015 (thanks @garethwhittaker)

Examples and TypeScript

A huge thanks to @presidenten for his work on the Phaser 3 Examples. You'll notice they now have a lovely screen shots for every example and the scripts generate them automatically :)

Also, thanks to the following for helping with the Phaser 3 Examples and TypeScript definitions, either by reporting errors, or even better, fixing them:

@madanus @truncs @samme

Phaser Doc Jam

The Phaser Doc Jam is an on-going effort to ensure that the Phaser 3 API has 100% documentation coverage. Thanks to the monumental effort of myself and the following people we're now really close to that goal! My thanks to:

31826615 - @16patsle - @bobonthenet - @rgk - @samme - @shaneMLK - @wemyss - ajmetal - andiCR - Arian Fornaris - bsparks - Carl - cyantree - DannyT - Elliott Wallace - felixnemis - griga - Hardylr - henriacle - Hsaka - icbat - Kanthi - Kyle - Lee - Nathaniel Foldan - Peter Pedersen - rootasjey - Sam Frantz - SBCGames - snowbillr - Stephen Hamilton - STuFF - TadejZupancic - telinc1

If you'd like to help finish off the last parts of documentation then take a look at the Doc Jam site.

- JavaScript
Published by photonstorm over 7 years ago

phaser - Phaser v3.13.0

Facebook Instant Games Plugin

Phaser 3.13 introduces the new Facebook Instant Games Plugin. The plugin provides a seamless bridge between Phaser and version 6.2 of the Facebook Instant Games SDK. Every single SDK function is available via the plugin and we will keep track of the official SDK to make sure they stay in sync.

The plugin offers the following features:

  • Easy integration with the Phaser Loader so load events update the Facebook progress circle.
  • Events for every plugin method, allowing the async calls of the SDK to be correctly inserted into the Phaser game flow. When SDK calls resolve they will surface naturally as a Phaser event and you'll know you can safely act upon them without potentially doing something mid-way through the game step.
  • All Plugin methods check if the call is part of the supported APIs available in the SDK, without needing to launch an async request first.
  • Instant access to platform, player and locale data.
  • Easily load player photos directly into the Texture Manager, ready for use with a Game Object.
  • Subscribe to game bots.
  • The plugin has a built-in Data Manager which makes dealing with data stored on Facebook seamless. Just create whatever data properties you need and they are automatically synced.
  • Support for FB stats, to retrieve, store and increment stats into cloud storage.
  • Save Session data with built-in session length validation.
  • Easy context switching, to swap between game instances and session data retrieval.
  • Easily open a Facebook share, invite, request or game challenge window and populate the text and image content using any image stored in the Texture cache.
  • Full Leaderboard support. Retrieve, scan and update leaderboard entries, as well as player matching.
  • Support for in-app purchases, with product catalogs, the ability to handle purchases, get past purchases and consume previously unlocked purchases.
  • Easily preload a set of interstitial ads, in both banner and video form, then display the ad at any point in your game, with in-built tracking of ads displayed and inventory available.
  • Plus other features, such as logging to FB Analytics, creating short cuts, switching games, etc.

The plugin is fully documented and official tutorials and project templates will follow shortly.

New Shape Game Objects

Phaser 3.13 has a new Game Object called Shape, which by itself isn't much use because it's a base class. However, extending that class are 11 different types of Shape (with more to come) and you can use it to create your own custom Shapes as well. Shapes are added to the display list in the exact same way as any other Game Object. For example:

this.add.rectangle(400, 300, 500, 120, 0x00ff00);

Here we're creating a new Rectangle shape. It's positioned at 400 x 300 in the Scene and has a size of 500 x 120 pixels. The final value is the fill color.

The thing to remember is that you can treat this Shape just like you'd treat any other Game Object. You can scale it, rotate it, alpha it, blend mode it, change its origin, give it a Camera scroll factor, put it inside a Container or Group, give it input abilities or even give it a physics body. It is, to all intents and purposes, a normal Game Object. The only difference is that when rendering it uses its own special bit of display code.

The shapes available are as follows:

  • GameObject.Arc - The arc allows you to draw either a circle, or part of a circle. You can set the start and end angle, if the rotation is clockwise or not, and even set the number of iterations the arc will use during rendering.
  • GameObject.Curve - The Curve Shape can take any Phaser Curve object, such as a Spline or Bezier Curve, and add it to the display list.
  • GameObject.Ellipse - An ellipse shape, which is essentially a circle with a differing width and height. It can be filled or stroked (or both!) and as with the arc you can set the 'smoothness' of it, allowing you to decrease the number of points used when creating its polygon data.
  • GameObject.Grid - The Grid Shape object allows you to generate them. You can set the width and height of the grid itself, as well as for the grid cells. The grid can either have a single color, or alternating cell colors and even have outline spacing between the cells, or not.
  • GameObject.Line - Create a Line Shape drawn between any two points, with a color and thickness. In WebGL you can also specify a different thickness for the start and end of the line.
  • GameObject.Polygon - A Polygon is effectively a list of points that is drawn between. The points can be provided in a number of different ways (as Vec2 objects, as an array, etc) and then you can either fill or stroke the resulting shape, or both.
  • GameObject.Rectangle - Simple, but powerful and endlessly useful. Set a width and height and it'll display a Rectangle, with control over the size, fill color and stroke color.
  • GameObject.Star - The Star shape does as its name suggests: it displays a star. You can control the number of points in the star as well as the inner and outer radius of it.
  • GameObject.Triangle - A Triangular shape with full control over the points used to make it and its fill and stroke colors. Internally it uses the batchFillTriangle method in WebGL, making it actually faster to draw than a Quad! Use them happily for bullets or abstract space ships, or anything else you feel like.
  • GameObject.IsoTriangle - This draws an isometric triangle, like a pyramid. You can control the colors of each face, if the pyramid is upside down or not and the width and height of it.
  • GameObject.IsoBox - This draws an isometric box. You can set the colors for each face of the box, as well as the projection angle and also which of the 3 faces are drawn.

All of the Shape objects render in both Canvas and WebGL and are available via the Game Object Factory.

Pointer and Input Event Updates

The specificity if the input events has been changed to allow you more control over event handling. Previously, the InputPlugin would emit the global pointerdown event first, and then the Game Object itself would emit the pointerdown event and finally the InputPlugin would emit the gameobjectdown event.

The order has now changed. The Game Object will dispatch its pointerdown event first. The InputPlugin will then dispatch gameobjectdown and finally the less specific of them all, pointerdown will be dispatched.

New in 3.13 is the ability to cancel this at any stage. All events are now sent an event object which you can call event.stopPropagation() on. This will immediately stop any further listeners from being invoked. If you call stopPropagation() after the first Game Object pointerdown event, then no more Game Object's will receive their callbacks and the InputPlugin will not dispatch either of its events.

This change has been introduced for pointerdown, pointerup, pointermove, pointerover and pointerout. No other data is included in the event object in this release.

  • The Game Object pointerdown callback signature has changed. It used to send pointer, x, y, camera to the listener. It now sends pointer, x, y, event to the listener. If you still need the camera property you can get it from pointer.camera.
  • The Game Object gameobjectdown callback signature has a new argument. It now sends event as the 3rd argument.
  • The pointerdown event, as dispatched by the InputPlugin, is now sent after the Game Object specific events (GameObject.pointerdown and gameobjectdown). This gives you the chance to cancel the event before the global listener receives it.
  • The Game Object pointerup callback signature has a new argument. It now sends the event as the 4th argument.
  • The Game Object gameobjectup callback signature has a new argument. It now sends event as the 3rd argument.
  • The pointerup event, as dispatched by the InputPlugin, is now sent after the Game Object specific events (GameObject.pointerup and gameobjectup). This gives you the chance to cancel the event before the global listener receives it.
  • The Game Object pointermove callback signature has a new argument. It now sends the event as the 4th argument.
  • The Game Object gameobjectmove callback signature has a new argument. It now sends event as the 3rd argument.
  • The pointermove event, as dispatched by the InputPlugin, is now sent after the Game Object specific events (GameObject.pointermove and gameobjectmove). This gives you the chance to cancel the event before the global listener receives it.
  • The Game Object pointerover callback signature has a new argument. It now sends the event as the 4th argument.
  • The Game Object gameobjectover callback signature has a new argument. It now sends event as the 3rd argument.
  • The pointerover event, as dispatched by the InputPlugin, is now sent after the Game Object specific events (GameObject.pointerover and gameobjectover). This gives you the chance to cancel the event before the global listener receives it.
  • The Game Object pointerout callback signature has a new argument. It now sends the event as the 2nd argument.
  • The Game Object gameobjectout callback signature has a new argument. It now sends event as the 3rd argument.
  • The pointerout event, as dispatched by the InputPlugin, is now sent after the Game Object specific events (GameObject.pointerout and gameobjectout). This gives you the chance to cancel the event before the global listener receives it.

Game Object List Updates

When Sprite's are created they are added to two lists within the Scene - the Display List and the Update List. Under 3.12 when a Scene was shut down it would emit a shutdown event, which Sprites listened out for. When they received it, they would destroy themselves.

After profiling and testing this process has changed slightly. Game Object's no longer listen for the Scene shutdown event. Instead, the Display List and Update List will iterate their children and call destroy on them in turn. If being destroyed by a Scene in this way, the child will skip several expensive operations in its destroy function. More importantly, in busy Scenes you no longer need thousands of event listeners registered. The result is that changing Scene is now up to 100% faster than before. You need not change your code to benefit from this, however, if you were relying on custom Game Objects listening for the Scene shutdown event natively, then this is no longer the case and you'll have to manually add that listener to your classes.

  • The UpdateList will now clear out its internal _list, _pendingRemoval and _pendingInsertion lists on shutdown. Before, it would only clear _list.
  • GameObject.destroy has a new optional boolean argument fromScene, which controls how the destroy process flows.

Camera Render to Texture

In 3.12 a new Camera method called setRenderToTexture was introduced. However, it had known issues so was placed under the experimental flag and you were advised not to use it unless in testing.

Thanks to several fixes in this release the experimental flag has been dropped and it's now safe to try using this new feature in production.

The method sets the Camera to render to a texture instead of to the main canvas. The Camera will redirect all Game Objects it's asked to render to this texture. During the render sequence, the texture itself will then be rendered to the main canvas.

Doing this gives you the ability to modify the texture before this happens, allowing for special effects such as Camera specific shaders, or post-processing on the texture.

  • Camera.setRenderToTexture is a new method that enables the Camera to render to a target texture instead of the main canvas, allowing for application of special effects at run-time.
  • Camera.clearRenderToTexture is a new method that stops a Camera from rendering to a texture and frees-up all associated resources.
  • Camera.setPipeline allows you to change the WebGL pipeline being used if the Camera is rendering to a texture, effectively swapping the active shader. Call with no arguments to clear the pipeline.
  • Camera.renderToTexture is a boolean property that controls where the Camera renders. It can be toggled on the fly.
  • Camera.canvas is a Canvas Element that the Camera will render to if running under the Canvas Renderer and rendering to a texture.
  • Camera.context is a Rendering Context that the Camera will render to if running under the Canvas Renderer and rendering to a texture.
  • Camera.glTexture is a WebGL Texture that the Camera will render to if running under the WebGL Renderer and rendering to a texture.
  • Camera.framebuffer is a WebGL Frame Buffer that the Camera will render to if running under the WebGL Renderer and rendering to a texture.
  • Camera.pipeline is the Pipeline that the Camera will render with if running under the WebGL Renderer and rendering to a texture with a pipeline set.
  • If you set a Camera to render to a texture then it will emit 2 events during the render loop. First, it will emit the event prerender. This happens right before any Game Object's are drawn to the Camera texture. Then, it will emit the event postrender. This happens after all Game Object's have been drawn, but right before the Camera texture is rendered to the main game canvas. It's the final point at which you can manipulate the texture before it appears in-game.

New Features

  • The Color object has a new property h which represents the hue of the color. You can tween or adjust this property in real-time and it will automatically update the internal RGB values with it.
  • The Color object has a new property s which represents the saturation of the color. You can tween or adjust this property in real-time and it will automatically update the internal RGB values with it.
  • The Color object has a new property v which represents the lightness value of the color. You can tween or adjust this property in real-time and it will automatically update the internal RGB values with it.
  • Color.setFromHSV is a new method that will set the color values based on the HSV values given.
  • Color.gray is a new method that will set the color to be a shade of gray based on the amount given.
  • Color.random is a new method that will set the color to be a random hue based on the min and max values given.
  • Color.randomGray is a new method that will set the color to be a random grayscale based on the min and max values given.
  • Color.saturate is a new method that will saturate the color based on the amount given. This is a chainable version of adjusting the saturation property directly.
  • Color.desaturate is a new method that will desaturate the color based on the amount given. This is a chainable version of adjusting the saturation property directly.
  • Color.lighten is a new method that will lighten the color based on the amount given. This is a chainable version of adjusting the value property directly.
  • Color.darken is a new method that will darken the color based on the amount given. This is a chainable version of adjusting the value property directly.
  • Color.brighten is a new method that will brighten the color based on the amount given.
  • The CanvasTexture class has a new property imageData which contains the ImageData of the texture.
  • The CanvasTexture class has a new property data which is a Uint8ClampedArray view into the buffer.
  • The CanvasTexture class has a new property pixels which is a Uint32Array view into the buffer.
  • The CanvasTexture class has a new property buffer which is an ArrayBuffer the same size as the context ImageData.
  • The CanvasTexture class has a new method update which refreshes the ImageData and ArrayBuffer based on the texture contents.
  • The CanvasTexture class has a new method draw which draws the given Image or Canvas element to the CanvasTexture, then updates the internal ImageData buffer and arrays.
  • The CanvasTexture class has a new method getPixel which will get the color of a specific pixel from the Canvas Texture and store it in the returned Color object. It uses the ArrayBuffer to do this, which is extremely fast, allowing for quick iteration across the canvas data.
  • The WebGLPipeline and WebGLRenderer have new a method setFloat1v which allows you to set a uniform1fv uniform value (thanks @Mattykins)
  • The WebGLPipeline and WebGLRenderer have new a method setFloat2v which allows you to set a uniform2fv uniform value (thanks @Mattykins)
  • The WebGLPipeline and WebGLRenderer have new a method setFloat3v which allows you to set a uniform3fv uniform value (thanks @Mattykins)
  • The WebGLPipeline and WebGLRenderer have new a method setFloat4v which allows you to set a uniform4fv uniform value (thanks @Mattykins)
  • Text.setLineSpacing is a new method that allows you to easily set the line spacing value of a Text object in a chainable call (thanks @RafelSanso)

Updates

  • The Graphics Canvas Renderer will now automatically call beginPath on the target context before processing the command stack. This has the effect of clearing off any sub-paths that may have persisted on the stack from previous Graphics objects or frames. This makes it more in-line with WebGL re: expectations when calling Graphics.clear.
  • initPipeline now defaults to the Texture Tint Pipeline if nothing else is specified. This allowed me to remove explicit strings from 11 different Game Objects, saving some bytes in the process.
  • The RGBToHSV function can now take an optional out argument, which is either a HSVColorObject or a Color object, and the results will be set into that object instead of creating a new one.
  • The HSVToRGB function can now take an optional out argument, which is either a HSVColorObject or a Color object, and the results will be set into that object instead of creating a new one.
  • Color.setTo has a new argument updateHSV which allows you to control if the internal HSV values are updated during the same call or not.
  • The Text._lineSpacing property has been renamed to lineSpacing and made public, not private. You still set it in the same way, by passing a lineSpacing property to the Text configuration object, but internally it's now clearer.
  • If a Scene is already active (i.e. running) and you call start on it (such as from another Scene) then it will shutdown the Scene first, before starting it again.

Bug Fixes

  • TileSprite.setTileScale would set the tile position by mistake, instead of the scale. Using the properties directly worked, but the method was incorrect (thanks @alexeymolchan)
  • Calling Text.setStyle would make the Text vanish if you didn't provide a resolution property in the style configuration object. Calling setStyle now only changes the properties given in the object, leaving any previously changed properties as-is. Fix #4011 (thanks @okcompewter)
  • In Matter.js if a body had its debug render.visible property set to false it wouldn't then render any other debug body beyond it. Now it will just skip bodies with hidden debug graphics (thanks @jf908)
  • If you flagged a Tween as paused in its config, never started it, and then called Tween.stop it wouldn't ever be removed from the _pending array. It's now moved to the Tween Manager's destroy list, ready for removal on the next frame. Fix #4023 (thanks @goldfire)
  • Game Objects would not remove themselves from the Scene's shutdown event handler when destroyed, leading to a build-up over time (thanks @goldfire)
  • The WebGL Renderer will no longer try and just resize a canvas backed texture, instead it will properly delete it then re-create it. Fix #4016 (thanks @alexeymolchan)
  • The Camera background for mini-Cameras (those positioned deep inside another Camera) would be offset incorrectly in WebGL, causing the background fills to be displaced (thanks @aaronfc)
  • The WebGL Renderer now always enables the SCISSOR_TEST, this allows Game Objects that use the scissor (such as custom objects, or Bitmap Text) to render properly again.
  • The Cameras setScene method, which is called automatically when a new Camera is created, will now call updateSystem which correctly increases the custom viewport counter. This fixes an issue with mini-cams inside of larger cameras not clipping their contents properly. If a Camera is moved to another Scene it also now correctly shrinks the total custom viewport counter.
  • Due to the two fixes above another bug was fixed: The ability for you to swap between Cameras with and without setRenderToTexture enabled with custom shaders. Previously if you used this with a custom shader then only the first Camera using the shader would render, the rest would appear black. Now, all Cameras using the custom shader work correctly. As a result all of the 'experimental' Camera rendering properties from 3.12 have been moved to stable.
  • If you destroyed a Game Object that had a custom cursor set during one of its input events the cursor didn't correctly reset. Fix #4033 (thanks @pantoninho)
  • RenderTexture.resize wouldn't correctly resize the texture under WebGL. Fix #4034 (thanks @jbpuryear)
  • Calling setFrame on a TileSprite wouldn't change the frame, it would just change the frame size. Fix #4039 (thanks @Jerenaux)
  • Zone.setRectangleDropZone used the wrong x and y coordinates for the hit area, causing it to be offset from the zone itself after the changes made for issue #3865 in the 3.12 release.

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@johanlindfors @Arthur3DLHC @JamesSkemp

- JavaScript
Published by photonstorm over 7 years ago

phaser - Phaser v3.12.0

Version 3.12.0 - Silica - 4th September 2018

FlatTintPipeline Updates

In 3.11 I overhauled the TextureTintPipeline, the WebGL batch used to render all texture based Game Objects, such as Sprites. In this release I did the same to the FlatTintPipeline. This pipeline was used exclusively by the Graphics Game Object to draw filled and stroked primitives in WebGL. It was also used by classes such as the Camera in order to draw their colored backgrounds and flash / fade effects.

When I looked closely at the shaders being used by the texture and graphics pipelines I noticed they were virtually identical. Yet if you were to mix Graphics objects and Sprites in your game, it would cause a complete batch flush as it switched between the them as it rebound the shaders, adding to both the draw calls and gl ops per frame.

The more I looked through the graphics pipeline, the more I saw the same kind of things the texture one previously had: duplicate vars, in-line matrix operations and so on. So I worked through the process of refactoring it, boiling it down to just a handful of core methods and re-using methods the texture pipeline already had. The end result is that I've been able to remove the FlatTintPipeline entirely. This saves 42.3KB (unminifed) and removes 1000 lines of code from the build. Of course, lots of the methods were added to the texture pipeline, but that only increased from 730 sloc to 1087 sloc, a fraction of the amount before! And the benefits don't end there.

If you had any custom pipelines that extended the FlatTintPipeline please update them to extend the TextureTintPipeline instead. You'll likely need to remap a few methods, but most of them remain the same. Double-check the method signatures though.

The same pipeline can now draw both graphics and sprites, with the same shader and no texture swapping either. This means you can happily mix Graphics objects alongside Sprites and it won't cost any extra overhead at all. There are more benefits too, which are outlined in the list below.

  • The TextureTintPipeline now has 100% jsdoc coverage.
  • The removal of the FlatTintPipeline shaves 42.3KB and 1000 sloc from the bundle size.
  • The Graphics fill and line styles are now cached in the pipeline, rather than being re-calculated for every primitive drawn.
  • The new batchTri method will add a triangle to the vertex batch, either textured or filled.
  • drawFillRect is a new method that will add an untransformed rectangle to the batch. These are used by things like Cameras to fill in background colors.
  • batchFillRect has been moved to the TextureTintPipeline and has a new much more concise method signature.
  • batchFillTriangle has been moved to the TextureTintPipeline and has a new much more concise method signature.
  • batchFillPath has been moved to the TextureTintPipeline and has a new much more concise method signature.
  • batchLine has been moved to the TextureTintPipeline.
  • When drawing Graphics paths with a line width of 1 it will no longer spend any time drawing the line joins, speeding-up the rendering of 1px lines.

WebGL Scissor Update

The process of managing scissors in the WebGLRenderer has been completely rewritten. Previously, the gl scissor was being constantly enabled and disabled for every Camera in your game, leading to pointless gl operations.

  • Cameras have a new internal method updateSystem which is automatically called if you change any Camera viewport values. This in turn tells the Scene Manager if there are any cameras with custom viewports, in any Scene of your game. If there are not then the scissor is never even enabled or set, meaning zero gl ops! If your game uses full sized Cameras it now doesn't cost anything at all with regard to scissoring.
  • If a new scissor is set it will now check to see if it's the same size and position as the current scissor, and if so, it'll skip setting it at all.

Render Texture New Features and Updates

The Render Texture class has been rewritten from scratch and all Game Objects have been updated to support it. Previously it was very restricted in what you could do with it. It used to have a matrix stack for internal transforms, but this has been replaced with a Camera instead. This means you have the full power of a Camera system (scrolling, zooming, rotation) but it only impacts the contents of the Render Texture.

  • The biggest update is the change in what the draw method can accept. Previously you had to pass in a texture and frame reference. This has changed, as has the method signature. It can now accept any of the following:

    • Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
    • Dynamic and Static 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. Pass in Scene.children to draw the whole display list.
    • Another Render Texture.
    • A Texture Frame instance.
    • A string. This is used to look-up a texture from the Texture Manager.
  • There is a new method drawFrame which allows you to pass in a string-based texture and frame key and have it drawn to the Render Texture.

  • The new method saveTexture allows you to save the Render Texture into the Texture Manager using your own key. You can then use the Render Texture for any Game Object that accepts textures as a source, such as Sprites or even Tilemap Layers. You can add frame data to a Render Texture using the RenderTexture.texture.add method.

  • The new camera property is an instance of a complete 2D Camera. You can use it to change the view into your Render Texture. Scroll, rotate, zoom, just like you would with a normal Camera, except it will only influence the objects being drawn to the Render Texture.

  • All of the matrix-style methods have been removed: save, translate, restore, scale, rotate. You can now achieve the same thing by either transforming the object you want to draw to the Render Texture, or using the built-in Camera.

  • You can now crop a Render Texture. Use the setCrop method to define the crop region.

See the fully complete documentation for more details and the extensive examples and tests created.

Text Game Object New Features and Updates

The Text Game Object has been given an internal overhaul to make it more flexible. Some properties have been renamed or moved and new features added:

  • Text can now be cropped in WebGL and Canvas! Use the setCrop method to crop the text.
  • Text now keeps a reference to the renderer in the renderer property.
  • The canvasTexture property has been removed.
  • Text now has internal texture and frame properties. These replace the old canvasTexture but perform the same task, while allowing for texture cropping and much smaller renderer code.
  • Previously, changing a Text object by setting its text property directly wouldn't change the text being rendered as using setText was the expected way to change what was being displayed. Internally the text property has been renamed to _text and flagged as private, and a new getter / setter for text has been added, which hands over to the setText method, meaning you can now use both ways of setting the text. Fix #3919 (thanks @hackhat @samid737)

Tile Sprite Object New Features and Updates

The Tile Sprite Game Object has been given an internal overhaul to make it more flexible. Some properties have been renamed or moved and new features added:

  • Tile Sprites can now be cropped in WebGL and Canvas! Use the setCrop method to crop the tile sprite.
  • There is a new method setTileScale which will set the tile scale in a chainable call.
  • There is a new internal canvas property. Tile Sprites work differently than before in Canvas mode: Previously they would use the fillRect command on the game canvas to draw themselves every frame, even if they hadn't changed. They now draw to an internal canvas only when their position or scale changes. This canvas is then drawn to the game canvas instead. It's faster, as it doesn't fillRect every frame and also allows you to draw them to other contexts, such as Render Textures.
  • There are two new internal properties _tilePosition and _tileScale which are Vector 2s that hold the position and scale. Getters have been added, so use the same properties as before in your code.
  • There are two new properties displayTexture and displayFrame. These replace the previous texture and frame properties and hold references to the source texture the Tile Sprite is using.
  • The canvasPattern property has been renamed to fillPattern.
  • The oldFrame property has been removed.
  • The canvasBuffer property has been renamed to fillCanvas.
  • The canvasBufferCtx property has been renamed to fillContext.

Tilemap New Features and Updates

The Tilemap and Dynamic and Static Tilemap Layer classes now all support 4 different modes of render order for drawing the tiles. This allows you to control the z-order of the tiles during render. This feature was requested by @etienne (who provided the test maps too) - see the new examples in the Labs for better understand the impact this has.

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 four draw orders are:

0 = right-down 1 = left-down 2 = right-up 3 = left-up

  • Tilemap has a new property renderOrder which is a string based version of the render order, as used when new layers are created via the map. If the map is created from Tiled JSON data, it will use whatever render order has been specified in the map data.
  • Tilemap has a new method setRenderOrder. This takes either an integer or a string-based version of the render order and stores it locally. It's then used during the creation of any layers from that point on.
  • The DynamicTilemapLayer has a new method setRenderOrder. This takes either an integer or a string-based version of the render order and stores it locally. It's then used during rendering of the layer. You can change the value on the fly.
  • The StaticTilemapLayer has a new method setRenderOrder. This takes either an integer or a string-based version of the render order and stores it locally. Under WebGL it will re-create the whole vertex buffer, using the new draw order. Under Canvas it uses it at run-time during rendering. You can change it on the fly.
  • ParseJSONTiled now extracts the renderorder property from the Tiled JSON.
  • MapData has a new renderOrder property, which is populated by the Tiled Parser.

Matter.js Updates

The version of Matter.js used by Phaser has been updated from 0.13.1 to 0.14.2. To clarify why we don't include Matter via npm, it's because we use a customized version of Matter that includes extra features and optimizations not yet found in the official library.

Most of the updates were about documentation and module namespacing, however those relevant to Phaser are listed below. You can also view the full Matter Change Log.

  • fix Composite.bounds global issue, closes #627, closes #544 (f7f77b4), closes #627 #544
  • updated pathseg library, closes #548, closes #602, closes #424 (1e5758f), closes #548 #602 #424
  • fix Common.isElement on node, closes #535 (ec38eeb), closes #535
  • added Query.collides, closes #478 (6593a72), closes #478
  • fix point argument of Body.scale, closes #428 (894c1ef), closes #428
  • fix Body.scale for compound bodies (50a89d0)
  • fix centroid for static compound bodies, closes #483 (ece66e6), closes #483
  • fix Common.isElement, closes #501, closes #507, closes #459, closes #468, closes #517 (18a0845), closes #501 #507 #459 #468 #517
  • fix inertia change in Body.setMass, closes #378 (f7d1877), closes #378
  • fix Vertices.chamfer radius argument, closes #467 (3bceef4), closes #467

Camera 3D Plugin

Support for Camera 3D and Sprite 3D Game Objects have been removed from the core Phaser bundle and moved to an optional plugin.

You can find the source for Camera 3D in the new plugins/camera3d folder, along with a README file explaining how to now use the plugin in your games.

  • When a Sprite3D object is added to a Camera via Camera.add it is now added to the Display and Update Lists. Fix #3945 (thanks @vvega)

New Features

  • Camera.resolution is a new read-only property that holds the current game config resolution that the camera is using. This is used internally for viewport calculations.
  • Text.resolution and the method Text.setResolution allows you to control the resolution of a Static Text Game Object. By default it will be set to match the resolution set in the Game Config, but you can override it yourself via the TextStyle. It allows for much clearer text on High DPI devices, at the cost of larger internal Canvas textures for the Text - so please use with caution, as the more high res Text you have, the more memory it uses up. Fix #3528 (thanks @kirillbunin)
  • TransformMatrix.getCSSMatrix will return a CSS transform matrix formatted string from the current matrix values.
  • CacheManager now creates a new cache called html which is used to store all loaded HTML snippets.
  • FileType.HTML is a new file type loader that will load an HTML snippet and store it in the new html cache. Access it via load.html (this method was previously used to load html to textures, please see load.htmlTexture for this feature now)
  • TransformMatrix.getX is a new method that return the x component from the given x and y values based on the current matrix. This is used heavily in the pipelines.
  • TransformMatrix.getY is a new method that return the y component from the given x and y values based on the current matrix. This is used heavily in the pipelines.
  • TransformMatrix.copyToArray is a new method that will copy the matrix values to the given array. It's the counter-part of copyFromArray.
  • Graphics.setTexture is a new WebGL only method that allows you to set a texture to be used when drawing the shapes on the Graphics object. You can also specify how the texture should be blended with the current fill or gradient colors. Note that the texture is not tiled, it is stretched to fit the shape being drawn.
  • Graphics.fillGradientStyle is a new WebGL only method that allows you to set a gradient for the shapes being filled. You can control the colors at the 4 corners of a rectangle. The colors are then blended automatically in the shader. Use of this feature is limited. For example, you cannot gradient fill a whole path or an arc, as it's made up of lots of triangles. But for quick gradient backgrounds or buttons it's perfect.
  • Graphics.lineGradientStyle is a new WebGL only method that allows you to set a gradient for the shapes being stroked. You can control the colors at the 4 corners of a rectangle. The colors are then blended automatically in the shader. Use of this feature is limited. For example, you cannot gradient stroke a whole path or an arc, as it's made up of lots of triangles. But for quick gradient lines it's perfect.
  • TextureManager.getBase64 is a new method that will take a texture frame key and return a base64 encoded version of the frame. You can also provide the image type and encoder options.
  • Global Plugins now have a new optional data object, the contents of which are passed to the plugins init method. This allows users to pass data directly into a plugin when added in the config: { key: 'BankPlugin', plugin: BankPluginV3, start: true, data: { gold: 5000 } } or when adding a plugin via the install method (thanks @samme)
  • You can now play animations in reverse! Use the new Sprite.anims.playReverse method to play a pre-defined animation in reverse from its starting frame. Or call Sprite.anims.reverse to immediately reverse the flow of an already running animation. Animations running in reverse still count towards the repeat total and respect the yoyo flag (thanks @khaleb85 @Ben-Millions)
  • The ParticleEmitterManager now has the Transform component. This means you can now set the position, rotation or scale of the Emitter Manager, and it will influence every Emitter it is rendering. The Managers transform is mixed with that of the Camera. This works in both Canvas and WebGL.
  • TextureManager.addRenderTexture is a new method that will add a Render Texture into the Texture Manager, allowing you to use it as the texture for Game Objects just by using the texture key. Modifying the source Render Texture will immediately modify any Game Objects using it.
  • TextureSource has a new boolean property isRenderTexture which is set automatically when it's created.
  • The Canvas Renderer has a new method setContext which allows it to swap the context being drawn to by all draw operations. Call the method with no arguments to reset it to the default game canvas.
  • If you set window.FORCE_WEBGL or window.FORCE_CANVAS in the window in which the Phaser game is loaded it will over-ride the renderer type setting in your game config, and force either WebGL or Canvas. This is handy for quickly testing the differences between renderers without having to do a new build each time.
  • TextureSource.source is a new property that contains the original source of the Texture image. It is cleared when the source is destroyed.
  • TransformMatrix.copyToContext is a new method that will copy the values from the Matrix to the given Canvas Rendering Context.
  • Phaser.Utils.String.UUID will return an RFC4122 complaint UUID as a string. This is used internally to avoid cache key conflicts, but is exposed for your own use as well.
  • There is a new Crop Component which is used by non-texture based Game Objects, such as Text and TileSprite. You either use TextureCrop or Crop, not both together on the same object.
  • TransformMatrix.setToContext is a new method that will set the values from the Matrix to the given Canvas Rendering Context using setTransform rather than transform.
  • SetTransform is a new Canvas Renderer function that consolidates the process of preparing a Game Object for rendering, without actually rendering it. This is used internally by the Graphics and Bitmap Text classes.
  • The Texture Manager has a new method called renameTexture which will let you rename a texture, changing the key to the new one given. All existing Game Objects will still maintain their reference, even after a rename.
  • When loading an SVG file you can now change the size of the SVG during the load process, before it is rendered to a texture. This is really helpful if you wish to increase SVGs that have small viewBoxes set, or want to try and reduce memory consumption from SVGs with extra large dimensions. You can either pass in a fixed width and height: this.load.svg('morty', 'file.svg', { width: 300, height: 600 }) or you can provide a scale factor instead: this.load.svg('morty', 'file.svg', { scale: 4 }) (thanks @ysraelJMM)
  • Polygon.Perimeter will return the perimeter for the given Polygon (thanks @iamchristopher)
  • Polygon.GetPoints will return 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. This is available as a static function and as the getPoints method on a Polygon (thanks @iamchristopher)

Updates

  • The Camera class has been split into two: BaseCamera which contains all of the core Camera functions and properties, and would serve as a great base for you to extend for your own custom Cameras, and Camera which is the same class name as previously. Camera extends the Base Camera and adds in follower support and the Special Effects. You don't need to update your code, even if currently extending a Camera, as they work the same as before.
  • Camera.x and Camera.y have been turned into getters / setters, mapped to the internal private values _x and _y respectively. This is so that setting the Camera viewport position directly will now update the new internal resolution calculation vars too.
  • Camera.setScene will now set the Cameras resolution property at the same time and update the internal viewport vars.
  • The Cull Tiles method used by the Dynamic Tilemap Layer has had a nice and significant optimization. It will now use the cull area dimensions to restrict the amount of tile iteration that takes place per layer, resulting in dramatic reductions in processing time on large layers, or multiple layers (thanks @tarsupin)
  • GameObject.willRender now takes a Camera as its only argument and uses it within the check. This has allowed me to remove 23 duplicate checks spread across the various Game Objects, all of which did the same thing, saving both KB and CPU time as the flags were being checked twice in most cases.
  • The file type loader HTML has been renamed to HTMLTexture. If you were using this then please change your calls from load.html to load.htmlTexture. The arguments remain the same.
  • The setBlendMode method in the WebGL Renderer now returns a boolean. True if a new blend mode was set, otherwise false. Previously it returned a reference to the renderer instance.
  • The method batchVertices in the TextureTintPipeline has been renamed to batchQuad which more accurately describes what it does.
  • In ArcadePhysics Body.setSize you can now choose to not pass width and height values to the method. If you do this it will check to see if the parent Game Object has a texture frame, and if so, it will use the frame sizes for the Body dimensions (thanks @tarsupin)
  • PluginCache.destroyCorePlugins will remove all core plugins from the cache. Be very careful calling this as Phaser cannot restart or create any new Scenes once this has been called.
  • PluginCache.destroyCustomPlugins will remove all custom plugins from the cache.
  • PluginManager.destroy will now clear all custom plugins from the Plugin Cache. This fixes an issue with not being able to destroy a Phaser game instance and restart it if it used a custom plugin (thanks jd.joshuadavison)
  • Game.destroy has a new boolean argument noReturn. If set it will remove all Core plugins when the game instance is destroyed. You cannot restart Phaser on the same web page after doing this, so only set it if you know you're done and don't need to run Phaser again.
  • The MouseManager will no longer process its native events if the manager reference has been removed (i.e. you move the pointer as the game is destroying itself)
  • The TouchManager will no longer process its native events if the manager reference has been removed (i.e. you move the pointer as the game is destroying itself)
  • Particle.color has been removed as it's now calculated during rendering to allow for Camera alpha support.
  • The Game boot event flow has changed slightly. The Game will now listen for a texturesready event, which is dispatched by the Texture Manager when the default textures have finished processing. Upon receiving this, the Game will emit the ready event, which all the other systems listen for and respond to. The difference is that the Renderer uses the texturesready event to ensure that it is the first thing to be activated, before any other system.
  • The WebGLRenderer has a new property blankTexture which is a reference to an empty 32x32 transparent WebGL Texture. This is used internally for things like rendering Graphics with no texture fills and where no other texture has been set.
  • The WebGLRenderer has a new method setBlankTexture which forces it to set the blank texture as the current texture. This is used after drawing a Render Texture to ensure no other object tries to draw to itself.
  • The StaticTilemapLayer has had the following properties and methods added to it: skipCull, tilesDrawn, tilesTotal, cullPaddingX, cullPaddingY, cullCallback, setSkipCull and setCullPadding as these are all used by the Canvas Static Layer renderer. Static Layers in 3.11 didn't render in Canvas because the cull values were missing, but now render correctly and can also be rendered to other targets, like a Render Texture.
  • The Math.Snap methods Snap.Floor, Snap.Ceil and Snap.To have all gained a new optional boolean argument divide. If set the resulting snapped value will be divided by the gap amount before returning. This is handy if you're trying to quickly snap a value into a grid or array location.
  • The currentBlendMode property has been removed from the Canvas Renderer and is no longer checked by any class. Blend modes are now set directly on the context to avoid state saving invalidation.
  • The currentAlpha property has been removed from the Canvas Renderer and is no longer checked by any class. Alpha values are now set directly on the context to avoid state saving invalidation.
  • TextureCrop and Crop have a new method resetCropObject which generates the crop data object required by Game Objects that support cropping. This allows us to remove duplicate code from a number of Game Objects and replace it with a single function call.
  • The Canvas Renderer has a new batchSprite method that consolidates the process of drawing a texture-based Game Object to the canvas. It processes the alpha, blend mode and matrix calculations in a single function and now is used by nearly all Game Object canvas renderers.
  • The batchTexture method in the Texture Tint Pipeline now supports cropped Game Objects and will adjust the drawn texture frame accordingly.
  • The Matrix Stack Component has been removed. It's no longer used internally and was just wasting space.
  • You can now specify the lineHeight of a Retro Font in the Retro Font Config object (thanks @FelixNemis)
  • When a Static Tilemap Layer is generated in WebGL it will use the Cameras roundPixels value to clamp the tile coordinates.
  • The CanvasRenderer.DrawImage function has been removed, as has the associated drawImage property from the Canvas Renderer as they're no longer used.
  • The CanvasRenderer.BlitImage function has been removed, as has the associated blitImage property from the Canvas Renderer as they're no longer used.
  • You can now access the Game instance directly from a Scene using this.game as long as it exists in the Scene's Injection Map, which it does by default. Be very careful what you do here: there's next to nothing you should actually use this for.
  • Camera.ignore can now take nested-arrays of Game Objects and also supports both Groups and Containers.
  • The changedata event dispatched by the Data Manager now includes the previous value as the 4th argument to the callback, so the event signature is now: parent, key, value, previousValue (thanks @iamchristopher)
  • The call to gl.clearColor is now skipped when clearBeforeRender is set to false (thanks @goldfire)
  • The calls to DistanceBetween have been replaced with DistanceSquared in the closest and furthest functions within Arcade Physics (thanks @Mursaat)
  • The RandomDataGenerator will now create a default random seed if you instantiate your own version of the class (instead of using Phaser.Math.RND) and don't provide a seed for it (thanks michaeld)
  • The Tilemap createFromObjects method will now add custom properties to the Game Objects. It works by checking if the property exists or not, and if not, it sets it in the Game Objects Data Manager (thanks @scalemailted @samme)
  • In Matter.js if you scaled a Body it would only scale correctly once, due to the way Matter handles scaling internally. We now automatically reset the Matter scale before applying the new value, which allows you to keep the Phaser and Matter object scales in sync. Fix #3785 #3951 (thanks @bergben)
  • The default Container Blend Mode is now SKIP_TEST. This allows you to either set a blend mode for a Container, in which case all children use that blend mode. Or, you can set a blend mode on the children and the children will render using their own blend modes, as the Container doesn't have one set. The WebGL and Canvas Renderer functions have also been updated to support this change. Fix #3684 (thanks @TadejZupancic)
  • Previously the Input Manager would create a Touch handler unless the Game Config had input.touch set to false (the default was true). If no such property is set, it no longer defaults to true and instead is set to whatever Device.input.touch returns. On non-touchscreen desktops this means it will now only create one single Pointer, rather than two.
  • The Arcade Physics Body _tempMatrix property has been removed. It was only used if the Body's Game Object had a parent. The matrix has been moved to the World instance instead, shared by all bodies.
  • Arcade Physics World has gained two new private properties _tempMatrix and _tempMatrix2. These are used by all bodies in the simulation that need a temporal matrix for calculations, rather than having their own instances.
  • The Input Manager has gained a new private property _tempMatrix2. This is used internally in the hitTest checks to avoid constant matrix creation.
  • The Transform Matrix has a new method applyInverse which will take an x/y position and inverse translate it through the current matrix.
  • Using keyboard.addKeys("W, A, S, D") would fail because of the spacing between the characters. addKeys will now trim the input allowing you to space characters out if you prefer (thanks @dhruvyad)
  • Calling setTimeScale on the Sprite's Animation component will now set the time scale value and keep it set until you change it again. Previously it would be reset to 1 when a new animation was loaded into the component, but this no longer happens - once the time scale is set it remains in effect, regardless of which animations are played on the Sprite.

Game Config Resolution Specific Bug Fixes

Setting the resolution property in the Game Config to a value other than 1 would cause various errors in the API. The following have been fixed:

  • The game canvas would be sized incorrectly, unless you had enabled auto resizing. It now scales the canvas to the size given, maintaining the resolution. Fix #3468 (thanks @Legomite)
  • Cameras with background colors set would display the filled color area at the wrong size. Camera fills now respect the resolution.
  • The Camera Fade Effect would display the fade fill rectangle at the wrong size. Camera fades now respect the resolution.
  • The Camera Flash Effect would display the fade fill rectangle at the wrong size. Camera flashes now respect the resolution.
  • The Camera Shake Effect would shake the Camera using the wrong width values. Camera Shakes now respect the resolution.
  • Input calculations would not factor in the Game Resolution correctly. If a Camera viewport was not at 0x0 or not the full size, or the Camera was rotated or zoomed, the input areas would be wrong if resolution was > 1. These are now factored in correctly and changing the resolution no longer breaks input. Fix #3606 (thanks @Secretmapper @thanh-taro)

Bug Fixes

  • The setCrop method stored its crop object on the prototype chain by mistake, causing all Images or Sprites that were cropped to display the same frame. The crop data has been moved to the Game Object instance, where it should be, fixing this issue (thanks NoxBrutalis)
  • If an AudioFile failed to load and throw an incomplete error, it would cause the console.log to crash JavaScript when trying to log the error. It now only logs the message if it exists. Fix #3830 (thanks @kelostrada)
  • Particles using a blend mode wouldn't render correctly after the updates in 3.11. If the blend mode changes during the processing of an emitter manager it'll now correctly rebind the texture, stopping the particles from vanishing. Fix #3851 (thanks @maxailloud)
  • Adding an array of children to a Group would cause it to mistakenly think you were passing a config object. Fix #3854 (thanks @pedro-w)
  • Graphics paths in WebGL would not render the line join between the final and the first path if the path was closed, leaving a noticeable gap if you used particularly thick strokes. If the path is closed it will now render the final line join properly.
  • If a Mesh caused a batch flush it would fail to render as its texture was lost. It's now rebound correctly after the flush.
  • ArcadePhysics.closest and ArcadePhysics.furthest used the wrong tree reference, causing them to throw errors (thanks @samme)
  • BlitterCanvasRenderer would fail to render a Bob in Canvas mode if it was flipped (thanks @SBCGames)
  • RenderTexture.draw would fail to draw the frame in Canvas mode (thanks @SBCGames)
  • ParticleEmitter would fail to draw a textured particle in Canvas mode (thanks @SBCGames)
  • RenderTexture.preDestroy will now release the canvas back to the CanvasPool if running in canvas mode (thanks @SBCGames)
  • The alpha value is now always set for Render Textures in canvas mode, regardless of the previous alpha value in the renderer (thanks @SBCGames)
  • Zone now calls updateDisplayOrigin in its constructor, causing the displayOriginX and displayOriginY values to now be correct if you create a Zone and then don't resize it. Fix #3865 (thanks @rexrainbow)
  • The CameraManager was accidentally adding extra destroy event calls when a Scene was restarted, causing an Uncaught TypeError: Cannot read property 'events' of null when trying to destroy a game instance having swapped from a Scene to another, and back again. Fix #3878 (thanks @mbunby)
  • RenderTextures in WebGL will now set the viewport size, stopping the console warning in Firefox. Fix #3823 (thanks @SBCGames)
  • Particles now take the Cameras alpha value into consideration when calculating their final alpha values in WebGL. They previously ignored it. If you now alpha a Camera out all particles will change accordingly.
  • The CullTiles updates from 3.11 didn't factor in the position of the Tilemap Layer to its bounds calculations, causing Static layers displayed out of the Camera viewport to never render in Canvas mode. The method has also been optimized further, with less divisions and less checks if culling is disabled.
  • The Particle Emitter when running in Canvas wouldn't allow more than 1 emitter to use a blend mode (as seen in the Electric examples). The blend mode is properly set for each emitter now.
  • The Blend Mode is now set directly in all Canvas Renderers without comparing it to what's stored in the Canvas Renderer. This fixes problems where the blend mode would be lost between two different Game Objects because they restored the context, but didn't update the renderer flag. Game Objects in Canvas can now mix and match blend modes across the display list.
  • Matter.js has received a tiny update that prevents collisionEnd from triggering many times when it should only trigger once (thanks @mikewesthad)
  • Graphics objects couldn't be set to be ignored by Cameras. Now every renderable Game Object can be ignored by a Camera, either directly or via a Container. The exception are Groups because they don't render and are non-exclusive parents.
  • The Tilemap Culling function now uses the Tilemap tile dimensions for its bounds calculations, instead of the layer tile sizes, as they two don't have to match and it's the underlying grid size that takes precedence when calculating visible tiles. Fix #3893 (thanks @Zax37)
  • The Arcade Physics Body.speed property is now set whenever you set the velocity via setVelocity or setVelocityX or setVelocityY which stops the body velocity being reset to zero if useDamping is enabled. Fix #3888 (thanks @samme)
  • The getPixelAlpha method in the Texture Manager wasn't using the correct frame name. This is now passed in correctly. Fix #3937 (thanks @goldfire)
  • The getPixelAlpha and getPixel methods in the Texture Manager would allow x/y coordinates from outside the cut area of a frame. It now tests to ensure they're within the frame. Fix #3937 (thanks @goldfire)
  • A Game Object couldn't have a blend mode of SKIP_TEST set by using the getter or the setBlendMode method.
  • In Arcade Physics the World.disable call was passing the wrong argument, so never disabling the actual body (thanks @samme)
  • There was a visual bug with Rounded Rectangles in Canvas mode, due to the addition of the overshoot argument in the Graphics arc call. This has been fixed, so arcs will now render correctly and consistently in WebGL and Canvas and Rounded Rectangles are back to normal again too. Fix #3912 (thanks @valse)
  • The InputManager.inputCandidate method, which determines if a Game Object can be interacted with by a given Pointer and Camera combination, now takes the full camera status into consideration. This means if a Camera is set to ignore a Game Object you can now no longer interact with it, or if the Camera is ignoring a Container with an interactive Game Object inside it, you cannot interact with the Container children anymore. Previously they would interact regardless of the Camera state. Fix #3984 (thanks @NemoStein @samid737)
  • Transform.getWorldTransformMatrix has been recoded to iterate the transform parents correctly, applying the matrix multiplications as it goes. This (along with some changes in the Input Manager) fix the issue with Game Objects inside of Containers failing hit tests between certain angles. Fix #3920 (thanks @chaping @hackhat)
  • Calling Arcade Physics collide during an update method wouldn't inject the results back into the Body parent, causing the bodies to carry on moving. Using Colliders worked, but manually checking did not. Now, both methods work. Fix #3777 (thanks @samme)
  • The setTintFill method would ignore the alpha value of the Game Object in the shader. The alpha value is now blended with the tint fill, allowing you to properly alpha out tint-filled Game Objects. Fix #3992 (thanks @trl-bsd)
  • Arcade Physics World collideSpriteVsTilemapLayer now syncs the collision results back to the body, allowing you to call collide from within an update loop once again. Fix #3999 (thanks @nkholski @mikewesthad)
  • Arcade Physics Body deltaX and deltaY methods will now return the previous steps delta values, rather than zero. Fix #3987 (thanks @HaoboZ)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@SBCGames @rgk @rook2pawn @robbintt @bguyl @halilcakarr @PhaserEditor2D @Edwin222 @tfelix @Yudikubota @hexus @guzmonne @ampled @thanh-taro @dcbriccetti @Dreaded-Gnu @padme-amidala @rootasjey @ampled @thejonanshow @polarstoat @jdjoshuadavison @alexeymolchan @samme @PBird @spontoreau @hypertrifle @kid-wumeng

Thanks to @khaleb85 for fixing the super-annoying lag on the API Docs pages when it hung the browser while indexing the search field.

- JavaScript
Published by photonstorm over 7 years ago

phaser - Phaser v3.12.0 Beta 3 Release

FlatTintPipeline Updates

In 3.11 I overhauled the TextureTintPipeline, the WebGL batch used to render all texture based Game Objects, such as Sprites. In this release I did the same to the FlatTintPipeline. This pipeline was used exclusively by the Graphics Game Object to draw filled and stroked primitives in WebGL. It was also used by classes such as the Camera in order to draw their colored backgrounds and flash / fade effects.

When I looked closely at the shaders being used by the texture and graphics pipelines I noticed they were virtually identical. Yet if you were to mix Graphics objects and Sprites in your game, it would cause a complete batch flush as it switched between the them as it rebound the shaders, adding to both the draw calls and gl ops per frame.

The more I looked through the graphics pipeline, the more I saw the same kind of things the texture one previously had: duplicate vars, in-line matrix operations and so on. So I worked through the process of refactoring it, boiling it down to just a handful of core methods and re-using methods the texture pipeline already had. The end result is that I've been able to remove the FlatTintPipeline entirely. This saves 42.3KB (unminifed) and removes 1000 lines of code from the build. Of course, lots of the methods were added to the texture pipeline, but that only increased from 730 sloc to 1087 sloc, a fraction of the amount before! And the benefits don't end there.

If you had any custom pipelines that extended the FlatTintPipeline please update them to extend the TextureTintPipeline instead. You'll likely need to remap a few methods, but most of them remain the same. Double-check the method signatures though.

The same pipeline can now draw both graphics and sprites, with the same shader and no texture swapping either. This means you can happily mix Graphics objects alongside Sprites and it won't cost any extra overhead at all. There are more benefits too, which are outlined in the list below.

  • The TextureTintPipeline now has 100% jsdoc coverage.
  • The removal of the FlatTintPipeline shaves 42.3KB and 1000 sloc from the bundle size.
  • The Graphics fill and line styles are now cached in the pipeline, rather than being re-calculated for every primitive drawn.
  • The new batchTri method will add a triangle to the vertex batch, either textured or filled.
  • drawFillRect is a new method that will add an untransformed rectangle to the batch. These are used by things like Cameras to fill in background colors.
  • batchFillRect has been moved to the TextureTintPipeline and has a new much more concise method signature.
  • batchFillTriangle has been moved to the TextureTintPipeline and has a new much more concise method signature.
  • batchFillPath has been moved to the TextureTintPipeline and has a new much more concise method signature.
  • batchLine has been moved to the TextureTintPipeline.
  • When drawing Graphics paths with a line width of 1 it will no longer spend any time drawing the line joins, speeding-up the rendering of 1px lines.

WebGL Scissor Update

The process of managing scissors in the WebGLRenderer has been completely rewritten. Previously, the gl scissor was being constantly enabled and disabled for every Camera in your game, leading to pointless gl operations.

  • Cameras have a new internal method updateSystem which is automatically called if you change any Camera viewport values. This in turn tells the Scene Manager if there are any cameras with custom viewports, in any Scene of your game. If there are not then the scissor is never even enabled or set, meaning zero gl ops! If your game uses full sized Cameras it now doesn't cost anything at all with regard to scissoring.
  • If a new scissor is set it will now check to see if it's the same size and position as the current scissor, and if so, it'll skip setting it at all.

Render Texture New Features and Updates

The Render Texture class has been rewritten from scratch and all Game Objects have been updated to support it. Previously it was very restricted in what you could do with it. It used to have a matrix stack for internal transforms, but this has been replaced with a Camera instead. This means you have the full power of a Camera system (scrolling, zooming, rotation) but it only impacts the contents of the Render Texture.

  • The biggest update is the change in what the draw method can accept. Previously you had to pass in a texture and frame reference. This has changed, as has the method signature. It can now accept any of the following:

    • Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
    • Dynamic and Static 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. Pass in Scene.children to draw the whole display list.
    • Another Render Texture.
    • A Texture Frame instance.
    • A string. This is used to look-up a texture from the Texture Manager.
  • There is a new method drawFrame which allows you to pass in a string-based texture and frame key and have it drawn to the Render Texture.

  • The new method saveTexture allows you to save the Render Texture into the Texture Manager using your own key. You can then use the Render Texture for any Game Object that accepts textures as a source, such as Sprites or even Tilemap Layers. You can add frame data to a Render Texture using the RenderTexture.texture.add method.

  • The new camera property is an instance of a complete 2D Camera. You can use it to change the view into your Render Texture. Scroll, rotate, zoom, just like you would with a normal Camera, except it will only influence the objects being drawn to the Render Texture.

  • All of the matrix-style methods have been removed: save, translate, restore, scale, rotate. You can now achieve the same thing by either transforming the object you want to draw to the Render Texture, or using the built-in Camera.

  • You can now crop a Render Texture. Use the setCrop method to define the crop region.

See the fully complete documentation for more details and the extensive examples and tests created.

Text Game Object New Features and Updates

The Text Game Object has been given an internal overhaul to make it more flexible. Some properties have been renamed or moved and new features added:

  • Text can now be cropped in WebGL and Canvas! Use the setCrop method to crop the text.
  • Text now keeps a reference to the renderer in the renderer property.
  • The canvasTexture property has been removed.
  • Text now has internal texture and frame properties. These replace the old canvasTexture but perform the same task, while allowing for texture cropping and much smaller renderer code.
  • Previously, changing a Text object by setting its text property directly wouldn't change the text being rendered as using setText was the expected way to change what was being displayed. Internally the text property has been renamed to _text and flagged as private, and a new getter / setter for text has been added, which hands over to the setText method, meaning you can now use both ways of setting the text. Fix #3919 (thanks @hackhat @samid737)

Tile Sprite Object New Features and Updates

The Tile Sprite Game Object has been given an internal overhaul to make it more flexible. Some properties have been renamed or moved and new features added:

  • Tile Sprites can now be cropped in WebGL and Canvas! Use the setCrop method to crop the tile sprite.
  • There is a new method setTileScale which will set the tile scale in a chainable call.
  • There is a new internal canvas property. Tile Sprites work differently than before in Canvas mode: Previously they would use the fillRect command on the game canvas to draw themselves every frame, even if they hadn't changed. They now draw to an internal canvas only when their position or scale changes. This canvas is then drawn to the game canvas instead. It's faster, as it doesn't fillRect every frame and also allows you to draw them to other contexts, such as Render Textures.
  • There are two new internal properties _tilePosition and _tileScale which are Vector 2s that hold the position and scale. Getters have been added, so use the same properties as before in your code.
  • There are two new properties displayTexture and displayFrame. These replace the previous texture and frame properties and hold references to the source texture the Tile Sprite is using.
  • The canvasPattern property has been renamed to fillPattern.
  • The oldFrame property has been removed.
  • The canvasBuffer property has been renamed to fillCanvas.
  • The canvasBufferCtx property has been renamed to fillContext.

Tilemap New Features and Updates

The Tilemap and Dynamic and Static Tilemap Layer classes now all support 4 different modes of render order for drawing the tiles. This allows you to control the z-order of the tiles during render. This feature was requested by @etienne (who provided the test maps too) - see the new examples in the Labs for better understand the impact this has.

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 four draw orders are:

0 = right-down 1 = left-down 2 = right-up 3 = left-up

  • Tilemap has a new property renderOrder which is a string based version of the render order, as used when new layers are created via the map. If the map is created from Tiled JSON data, it will use whatever render order has been specified in the map data.
  • Tilemap has a new method setRenderOrder. This takes either an integer or a string-based version of the render order and stores it locally. It's then used during the creation of any layers from that point on.
  • The DynamicTilemapLayer has a new method setRenderOrder. This takes either an integer or a string-based version of the render order and stores it locally. It's then used during rendering of the layer. You can change the value on the fly.
  • The StaticTilemapLayer has a new method setRenderOrder. This takes either an integer or a string-based version of the render order and stores it locally. Under WebGL it will re-create the whole vertex buffer, using the new draw order. Under Canvas it uses it at run-time during rendering. You can change it on the fly.
  • ParseJSONTiled now extracts the renderorder property from the Tiled JSON.
  • MapData has a new renderOrder property, which is populated by the Tiled Parser.

Matter.js Updates

The version of Matter.js used by Phaser has been updated from 0.13.1 to 0.14.2. To clarify why we don't include Matter via npm, it's because we use a customized version of Matter that includes extra features and optimizations not yet found in the official library.

Most of the updates were about documentation and module namespacing, however those relevant to Phaser are listed below. You can also view the full Matter Change Log.

  • fix Composite.bounds global issue, closes #627, closes #544 (f7f77b4), closes #627 #544
  • updated pathseg library, closes #548, closes #602, closes #424 (1e5758f), closes #548 #602 #424
  • fix Common.isElement on node, closes #535 (ec38eeb), closes #535
  • added Query.collides, closes #478 (6593a72), closes #478
  • fix point argument of Body.scale, closes #428 (894c1ef), closes #428
  • fix Body.scale for compound bodies (50a89d0)
  • fix centroid for static compound bodies, closes #483 (ece66e6), closes #483
  • fix Common.isElement, closes #501, closes #507, closes #459, closes #468, closes #517 (18a0845), closes #501 #507 #459 #468 #517
  • fix inertia change in Body.setMass, closes #378 (f7d1877), closes #378
  • fix Vertices.chamfer radius argument, closes #467 (3bceef4), closes #467

Camera 3D Plugin

Support for Camera 3D and Sprite 3D Game Objects have been removed from the core Phaser bundle and moved to an optional plugin.

You can find the source for Camera 3D in the new plugins/camera3d folder, along with a README file explaining how to now use the plugin in your games.

  • When a Sprite3D object is added to a Camera via Camera.add it is now added to the Display and Update Lists. Fix #3945 (thanks @vvega)

New Features

  • Camera.resolution is a new read-only property that holds the current game config resolution that the camera is using. This is used internally for viewport calculations.
  • Text.resolution and the method Text.setResolution allows you to control the resolution of a Static Text Game Object. By default it will be set to match the resolution set in the Game Config, but you can override it yourself via the TextStyle. It allows for much clearer text on High DPI devices, at the cost of larger internal Canvas textures for the Text - so please use with caution, as the more high res Text you have, the more memory it uses up. Fix #3528 (thanks @kirillbunin)
  • TransformMatrix.getCSSMatrix will return a CSS transform matrix formatted string from the current matrix values.
  • CacheManager now creates a new cache called html which is used to store all loaded HTML snippets.
  • FileType.HTML is a new file type loader that will load an HTML snippet and store it in the new html cache. Access it via load.html (this method was previously used to load html to textures, please see load.htmlTexture for this feature now)
  • TransformMatrix.getX is a new method that return the x component from the given x and y values based on the current matrix. This is used heavily in the pipelines.
  • TransformMatrix.getY is a new method that return the y component from the given x and y values based on the current matrix. This is used heavily in the pipelines.
  • TransformMatrix.copyToArray is a new method that will copy the matrix values to the given array. It's the counter-part of copyFromArray.
  • Graphics.setTexture is a new WebGL only method that allows you to set a texture to be used when drawing the shapes on the Graphics object. You can also specify how the texture should be blended with the current fill or gradient colors. Note that the texture is not tiled, it is stretched to fit the shape being drawn.
  • Graphics.fillGradientStyle is a new WebGL only method that allows you to set a gradient for the shapes being filled. You can control the colors at the 4 corners of a rectangle. The colors are then blended automatically in the shader. Use of this feature is limited. For example, you cannot gradient fill a whole path or an arc, as it's made up of lots of triangles. But for quick gradient backgrounds or buttons it's perfect.
  • Graphics.lineGradientStyle is a new WebGL only method that allows you to set a gradient for the shapes being stroked. You can control the colors at the 4 corners of a rectangle. The colors are then blended automatically in the shader. Use of this feature is limited. For example, you cannot gradient stroke a whole path or an arc, as it's made up of lots of triangles. But for quick gradient lines it's perfect.
  • TextureManager.getBase64 is a new method that will take a texture frame key and return a base64 encoded version of the frame. You can also provide the image type and encoder options.
  • Global Plugins now have a new optional data object, the contents of which are passed to the plugins init method. This allows users to pass data directly into a plugin when added in the config: { key: 'BankPlugin', plugin: BankPluginV3, start: true, data: { gold: 5000 } } or when adding a plugin via the install method (thanks @samme)
  • You can now play animations in reverse! Use the new Sprite.anims.playReverse method to play a pre-defined animation in reverse from its starting frame. Or call Sprite.anims.reverse to immediately reverse the flow of an already running animation. Animations running in reverse still count towards the repeat total and respect the yoyo flag (thanks @khaleb85)
  • The ParticleEmitterManager now has the Transform component. This means you can now set the position, rotation or scale of the Emitter Manager, and it will influence every Emitter it is rendering. The Managers transform is mixed with that of the Camera. This works in both Canvas and WebGL.
  • TextureManager.addRenderTexture is a new method that will add a Render Texture into the Texture Manager, allowing you to use it as the texture for Game Objects just by using the texture key. Modifying the source Render Texture will immediately modify any Game Objects using it.
  • TextureSource has a new boolean property isRenderTexture which is set automatically when it's created.
  • The Canvas Renderer has a new method setContext which allows it to swap the context being drawn to by all draw operations. Call the method with no arguments to reset it to the default game canvas.
  • If you set window.FORCE_WEBGL or window.FORCE_CANVAS in the window in which the Phaser game is loaded it will over-ride the renderer type setting in your game config, and force either WebGL or Canvas. This is handy for quickly testing the differences between renderers without having to do a new build each time.
  • TextureSource.source is a new property that contains the original source of the Texture image. It is cleared when the source is destroyed.
  • TransformMatrix.copyToContext is a new method that will copy the values from the Matrix to the given Canvas Rendering Context.
  • Phaser.Utils.String.UUID will return an RFC4122 complaint UUID as a string. This is used internally to avoid cache key conflicts, but is exposed for your own use as well.
  • There is a new Crop Component which is used by non-texture based Game Objects, such as Text and TileSprite. You either use TextureCrop or Crop, not both together on the same object.
  • TransformMatrix.setToContext is a new method that will set the values from the Matrix to the given Canvas Rendering Context using setTransform rather than transform.
  • SetTransform is a new Canvas Renderer function that consolidates the process of preparing a Game Object for rendering, without actually rendering it. This is used internally by the Graphics and Bitmap Text classes.
  • The Texture Manager has a new method called renameTexture which will let you rename a texture, changing the key to the new one given. All existing Game Objects will still maintain their reference, even after a rename.
  • When loading an SVG file you can now change the size of the SVG during the load process, before it is rendered to a texture. This is really helpful if you wish to increase SVGs that have small viewBoxes set, or want to try and reduce memory consumption from SVGs with extra large dimensions. You can either pass in a fixed width and height: this.load.svg('morty', 'file.svg', { width: 300, height: 600 }) or you can provide a scale factor instead: this.load.svg('morty', 'file.svg', { scale: 4 }) (thanks @ysraelJMM)

Updates

  • The Camera class has been split into two: BaseCamera which contains all of the core Camera functions and properties, and would serve as a great base for you to extend for your own custom Cameras, and Camera which is the same class name as previously. Camera extends the Base Camera and adds in follower support and the Special Effects. You don't need to update your code, even if currently extending a Camera, as they work the same as before.
  • Camera.x and Camera.y have been turned into getters / setters, mapped to the internal private values _x and _y respectively. This is so that setting the Camera viewport position directly will now update the new internal resolution calculation vars too.
  • Camera.setScene will now set the Cameras resolution property at the same time and update the internal viewport vars.
  • The Cull Tiles method used by the Dynamic Tilemap Layer has had a nice and significant optimization. It will now use the cull area dimensions to restrict the amount of tile iteration that takes place per layer, resulting in dramatic reductions in processing time on large layers, or multiple layers (thanks @tarsupin)
  • GameObject.willRender now takes a Camera as its only argument and uses it within the check. This has allowed me to remove 23 duplicate checks spread across the various Game Objects, all of which did the same thing, saving both KB and CPU time as the flags were being checked twice in most cases.
  • The file type loader HTML has been renamed to HTMLTexture. If you were using this then please change your calls from load.html to load.htmlTexture. The arguments remain the same.
  • The setBlendMode method in the WebGL Renderer now returns a boolean. True if a new blend mode was set, otherwise false. Previously it returned a reference to the renderer instance.
  • The method batchVertices in the TextureTintPipeline has been renamed to batchQuad which more accurately describes what it does.
  • In ArcadePhysics Body.setSize you can now choose to not pass width and height values to the method. If you do this it will check to see if the parent Game Object has a texture frame, and if so, it will use the frame sizes for the Body dimensions (thanks @tarsupin)
  • PluginCache.destroyCorePlugins will remove all core plugins from the cache. Be very careful calling this as Phaser cannot restart or create any new Scenes once this has been called.
  • PluginCache.destroyCustomPlugins will remove all custom plugins from the cache.
  • PluginManager.destroy will now clear all custom plugins from the Plugin Cache. This fixes an issue with not being able to destroy a Phaser game instance and restart it if it used a custom plugin (thanks jd.joshuadavison)
  • Game.destroy has a new boolean argument noReturn. If set it will remove all Core plugins when the game instance is destroyed. You cannot restart Phaser on the same web page after doing this, so only set it if you know you're done and don't need to run Phaser again.
  • The MouseManager will no longer process its native events if the manager reference has been removed (i.e. you move the pointer as the game is destroying itself)
  • The TouchManager will no longer process its native events if the manager reference has been removed (i.e. you move the pointer as the game is destroying itself)
  • Particle.color has been removed as it's now calculated during rendering to allow for Camera alpha support.
  • The Game boot event flow has changed slightly. The Game will now listen for a texturesready event, which is dispatched by the Texture Manager when the default textures have finished processing. Upon receiving this, the Game will emit the ready event, which all the other systems listen for and respond to. The difference is that the Renderer uses the texturesready event to ensure that it is the first thing to be activated, before any other system.
  • The WebGLRenderer has a new property blankTexture which is a reference to an empty 32x32 transparent WebGL Texture. This is used internally for things like rendering Graphics with no texture fills and where no other texture has been set.
  • The WebGLRenderer has a new method setBlankTexture which forces it to set the blank texture as the current texture. This is used after drawing a Render Texture to ensure no other object tries to draw to itself.
  • The StaticTilemapLayer has had the following properties and methods added to it: skipCull, tilesDrawn, tilesTotal, cullPaddingX, cullPaddingY, cullCallback, setSkipCull and setCullPadding as these are all used by the Canvas Static Layer renderer. Static Layers in 3.11 didn't render in Canvas because the cull values were missing, but now render correctly and can also be rendered to other targets, like a Render Texture.
  • The Math.Snap methods Snap.Floor, Snap.Ceil and Snap.To have all gained a new optional boolean argument divide. If set the resulting snapped value will be divided by the gap amount before returning. This is handy if you're trying to quickly snap a value into a grid or array location.
  • The currentBlendMode property has been removed from the Canvas Renderer and is no longer checked by any class. Blend modes are now set directly on the context to avoid state saving invalidation.
  • The currentAlpha property has been removed from the Canvas Renderer and is no longer checked by any class. Alpha values are now set directly on the context to avoid state saving invalidation.
  • TextureCrop and Crop have a new method resetCropObject which generates the crop data object required by Game Objects that support cropping. This allows us to remove duplicate code from a number of Game Objects and replace it with a single function call.
  • The Canvas Renderer has a new batchSprite method that consolidates the process of drawing a texture-based Game Object to the canvas. It processes the alpha, blend mode and matrix calculations in a single function and now is used by nearly all Game Object canvas renderers.
  • The batchTexture method in the Texture Tint Pipeline now supports cropped Game Objects and will adjust the drawn texture frame accordingly.
  • The Matrix Stack Component has been removed. It's no longer used internally and was just wasting space.
  • You can now specify the lineHeight of a Retro Font in the Retro Font Config object (thanks @FelixNemis)
  • When a Static Tilemap Layer is generated in WebGL it will use the Cameras roundPixels value to clamp the tile coordinates.
  • The CanvasRenderer.DrawImage function has been removed, as has the associated drawImage property from the Canvas Renderer as they're no longer used.
  • The CanvasRenderer.BlitImage function has been removed, as has the associated blitImage property from the Canvas Renderer as they're no longer used.
  • You can now access the Game instance directly from a Scene using this.game as long as it exists in the Scene's Injection Map, which it does by default. Be very careful what you do here: there's next to nothing you should actually use this for.
  • Camera.ignore can now take nested-arrays of Game Objects and also supports both Groups and Containers.
  • The changedata event dispatched by the Data Manager now includes the previous value as the 4th argument to the callback, so the event signature is now: parent, key, value, previousValue (thanks @iamchristopher)
  • The call to gl.clearColor is now skipped when clearBeforeRender is set to false (thanks @goldfire)
  • The calls to DistanceBetween have been replaced with DistanceSquared in the closest and furthest functions within Arcade Physics (thanks @Mursaat)
  • The RandomDataGenerator will now create a default random seed if you instantiate your own version of the class (instead of using Phaser.Math.RND) and don't provide a seed for it (thanks michaeld)
  • The Tilemap createFromObjects method will now add custom properties to the Game Objects. It works by checking if the property exists or not, and if not, it sets it in the Game Objects Data Manager (thanks @scalemailted @samme)
  • In Matter.js if you scaled a Body it would only scale correctly once, due to the way Matter handles scaling internally. We now automatically reset the Matter scale before applying the new value, which allows you to keep the Phaser and Matter object scales in sync. Fix #3785 #3951 (thanks @bergben)
  • The default Container Blend Mode is now SKIP_TEST. This allows you to either set a blend mode for a Container, in which case all children use that blend mode. Or, you can set a blend mode on the children and the children will render using their own blend modes, as the Container doesn't have one set. The WebGL and Canvas Renderer functions have also been updated to support this change. Fix #3684 (thanks @TadejZupancic)
  • Previously the Input Manager would create a Touch handler unless the Game Config had input.touch set to false (the default was true). If no such property is set, it no longer defaults to true and instead is set to whatever Device.input.touch returns. On non-touchscreen desktops this means it will now only create one single Pointer, rather than two.

Game Config Resolution Specific Bug Fixes

Setting the resolution property in the Game Config to a value other than 1 would cause various errors in the API. The following have been fixed:

  • The game canvas would be sized incorrectly, unless you had enabled auto resizing. It now scales the canvas to the size given, maintaining the resolution. Fix #3468 (thanks @Legomite)
  • Cameras with background colors set would display the filled color area at the wrong size. Camera fills now respect the resolution.
  • The Camera Fade Effect would display the fade fill rectangle at the wrong size. Camera fades now respect the resolution.
  • The Camera Flash Effect would display the fade fill rectangle at the wrong size. Camera flashes now respect the resolution.
  • The Camera Shake Effect would shake the Camera using the wrong width values. Camera Shakes now respect the resolution.
  • Input calculations would not factor in the Game Resolution correctly. If a Camera viewport was not at 0x0 or not the full size, or the Camera was rotated or zoomed, the input areas would be wrong if resolution was > 1. These are now factored in correctly and changing the resolution no longer breaks input. Fix #3606 (thanks @Secretmapper)

Bug Fixes

  • The setCrop method stored its crop object on the prototype chain by mistake, causing all Images or Sprites that were cropped to display the same frame. The crop data has been moved to the Game Object instance, where it should be, fixing this issue (thanks NoxBrutalis)
  • If an AudioFile failed to load and throw an incomplete error, it would cause the console.log to crash JavaScript when trying to log the error. It now only logs the message if it exists. Fix #3830 (thanks @kelostrada)
  • Particles using a blend mode wouldn't render correctly after the updates in 3.11. If the blend mode changes during the processing of an emitter manager it'll now correctly rebind the texture, stopping the particles from vanishing. Fix #3851 (thanks @maxailloud)
  • Adding an array of children to a Group would cause it to mistakenly think you were passing a config object. Fix #3854 (thanks @pedro-w)
  • Graphics paths in WebGL would not render the line join between the final and the first path if the path was closed, leaving a noticeable gap if you used particularly thick strokes. If the path is closed it will now render the final line join properly.
  • If a Mesh caused a batch flush it would fail to render as its texture was lost. It's now rebound correctly after the flush.
  • ArcadePhysics.closest and ArcadePhysics.furthest used the wrong tree reference, causing them to throw errors (thanks @samme)
  • BlitterCanvasRenderer would fail to render a Bob in Canvas mode if it was flipped (thanks @SBCGames)
  • RenderTexture.draw would fail to draw the frame in Canvas mode (thanks @SBCGames)
  • ParticleEmitter would fail to draw a textured particle in Canvas mode (thanks @SBCGames)
  • RenderTexture.preDestroy will now release the canvas back to the CanvasPool if running in canvas mode (thanks @SBCGames)
  • The alpha value is now always set for Render Textures in canvas mode, regardless of the previous alpha value in the renderer (thanks @SBCGames)
  • Zone now calls updateDisplayOrigin in its constructor, causing the displayOriginX and displayOriginY values to now be correct if you create a Zone and then don't resize it. Fix #3865 (thanks @rexrainbow)
  • The CameraManager was accidentally adding extra destroy event calls when a Scene was restarted, causing an Uncaught TypeError: Cannot read property 'events' of null when trying to destroy a game instance having swapped from a Scene to another, and back again. Fix #3878 (thanks @mbunby)
  • RenderTextures in WebGL will now set the viewport size, stopping the console warning in Firefox. Fix #3823 (thanks @SBCGames)
  • Particles now take the Cameras alpha value into consideration when calculating their final alpha values in WebGL. They previously ignored it. If you now alpha a Camera out all particles will change accordingly.
  • The CullTiles updates from 3.11 didn't factor in the position of the Tilemap Layer to its bounds calculations, causing Static layers displayed out of the Camera viewport to never render in Canvas mode. The method has also been optimized further, with less divisions and less checks if culling is disabled.
  • The Particle Emitter when running in Canvas wouldn't allow more than 1 emitter to use a blend mode (as seen in the Electric examples). The blend mode is properly set for each emitter now.
  • The Blend Mode is now set directly in all Canvas Renderers without comparing it to what's stored in the Canvas Renderer. This fixes problems where the blend mode would be lost between two different Game Objects because they restored the context, but didn't update the renderer flag. Game Objects in Canvas can now mix and match blend modes across the display list.
  • Matter.js has received a tiny update that prevents collisionEnd from triggering many times when it should only trigger once (thanks @mikewesthad)
  • Graphics objects couldn't be set to be ignored by Cameras. Now every renderable Game Object can be ignored by a Camera, either directly or via a Container. The exception are Groups because they don't render and are non-exclusive parents.
  • The Tilemap Culling function now uses the Tilemap tile dimensions for its bounds calculations, instead of the layer tile sizes, as they two don't have to match and it's the underlying grid size that takes precedence when calculating visible tiles. Fix #3893 (thanks @Zax37)
  • The Arcade Physics Body.speed property is now set whenever you set the velocity via setVelocity or setVelocityX or setVelocityY which stops the body velocity being reset to zero if useDamping is enabled. Fix #3888 (thanks @samme)
  • The getPixelAlpha method in the Texture Manager wasn't using the correct frame name. This is now passed in correctly. Fix #3937 (thanks @goldfire)
  • The getPixelAlpha and getPixel methods in the Texture Manager would allow x/y coordinates from outside the cut area of a frame. It now tests to ensure they're within the frame. Fix #3937 (thanks @goldfire)
  • A Game Object couldn't have a blend mode of SKIP_TEST set by using the getter or the setBlendMode method.
  • In Arcade Physics the World.disable call was passing the wrong argument, so never disabling the actual body (thanks @samme)
  • There was a visual bug with Rounded Rectangles in Canvas mode, due to the addition of the overshoot argument in the Graphics arc call. This has been fixed, so arcs will now render correctly and consistently in WebGL and Canvas and Rounded Rectangles are back to normal again too. Fix #3912 (thanks @valse)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@SBCGames @rgk @rook2pawn @robbintt @bguyl @halilcakarr @PhaserEditor2D @Edwin222 @tfelix @Yudikubota @hexus @guzmonne @ampled @thanh-taro @dcbriccetti @Dreaded-Gnu @padme-amidala @rootasjey @ampled @thejonanshow @polarstoat @jdjoshuadavison @alexeymolchan @samme

Thanks to @khaleb85 for fixing the super-annoying lag on the API Docs pages when it hung the browser while indexing the search field.

- JavaScript
Published by photonstorm almost 8 years ago

phaser - Phaser v3.12.0 Beta 2 Release

FlatTintPipeline Updates

In 3.11 I overhauled the TextureTintPipeline, the WebGL batch used to render all texture based Game Objects, such as Sprites. In this release I did the same to the FlatTintPipeline. This pipeline was used exclusively by the Graphics Game Object to draw filled and stroked primitives in WebGL. It was also used by classes such as the Camera in order to draw their colored backgrounds and flash / fade effects.

When I looked closely at the shaders being used by the texture and graphics pipelines I noticed they were virtually identical. Yet if you were to mix Graphics objects and Sprites in your game, it would cause a complete batch flush as it switched between the them as it rebound the shaders, adding to both the draw calls and gl ops per frame.

The more I looked through the graphics pipeline, the more I saw the same kind of things the texture one previously had: duplicate vars, in-line matrix operations and so on. So I worked through the process of refactoring it, boiling it down to just a handful of core methods and re-using methods the texture pipeline already had. The end result is that I've been able to remove the FlatTintPipeline entirely. This saves 42.3KB (unminifed) and removes 1000 lines of code from the build. Of course, lots of the methods were added to the texture pipeline, but that only increased from 730 sloc to 1087 sloc, a fraction of the amount before! And the benefits don't end there.

If you had any custom pipelines that extended the FlatTintPipeline please update them to extend the TextureTintPipeline instead. You'll likely need to remap a few methods, but most of them remain the same. Double-check the method signatures though.

The same pipeline can now draw both graphics and sprites, with the same shader and no texture swapping either. This means you can happily mix Graphics objects alongside Sprites and it won't cost any extra overhead at all. There are more benefits too, which are outlined in the list below.

  • The TextureTintPipeline now has 100% jsdoc coverage.
  • The removal of the FlatTintPipeline shaves 42.3KB and 1000 sloc from the bundle size.
  • The Graphics fill and line styles are now cached in the pipeline, rather than being re-calculated for every primitive drawn.
  • The new batchTri method will add a triangle to the vertex batch, either textured or filled.
  • drawFillRect is a new method that will add an untransformed rectangle to the batch. These are used by things like Cameras to fill in background colors.
  • batchFillRect has been moved to the TextureTintPipeline and has a new much more concise method signature.
  • batchFillTriangle has been moved to the TextureTintPipeline and has a new much more concise method signature.
  • batchFillPath has been moved to the TextureTintPipeline and has a new much more concise method signature.
  • batchLine has been moved to the TextureTintPipeline.
  • When drawing Graphics paths with a line width of 1 it will no longer spend any time drawing the line joins, speeding-up the rendering of 1px lines.

WebGL Scissor Update

The process of managing scissors in the WebGLRenderer has been completely rewritten. Previously, the gl scissor was being constantly enabled and disabled for every Camera in your game, leading to pointless gl operations.

  • Cameras have a new internal method updateSystem which is automatically called if you change any Camera viewport values. This in turn tells the Scene Manager if there are any cameras with custom viewports, in any Scene of your game. If there are not then the scissor is never even enabled or set, meaning zero gl ops! If your game uses full sized Cameras it now doesn't cost anything at all with regard to scissoring.
  • If a new scissor is set it will now check to see if it's the same size and position as the current scissor, and if so, it'll skip setting it at all.

Render Texture New Features and Updates

The Render Texture class has been rewritten from scratch and all Game Objects have been updated to support it. Previously it was very restricted in what you could do with it. It used to have a matrix stack for internal transforms, but this has been replaced with a Camera instead. This means you have the full power of a Camera system (scrolling, zooming, rotation) but it only impacts the contents of the Render Texture.

  • The biggest update is the change in what the draw method can accept. Previously you had to pass is a texture and frame reference. This has changed, as has the method signature. It can now accept any of the following:

    • Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
    • Dynamic and Static 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. Pass in Scene.children to draw the whole display list.
    • Another Render Texture.
    • A Texture Frame instance.
    • A string. This is used to look-up a texture from the Texture Manager.
  • There is a new method drawFrame which allows you to pass in a string-based texture and frame key and have it drawn to the Render Texture.

  • The new method saveTexture allows you to save the Render Texture into the Texture Manager using your own key. You can then use the Render Texture for any Game Object that accepts textures as a source, such as Sprites or even Tilemap Layers. You can add frame data to a Render Texture using the RenderTexture.texture.add method.

  • The new camera property is an instance of a complete 2D Camera. You can use it to change the view into your Render Texture. Scroll, rotate, zoom, just like you would with a normal Camera, except it will only influence is the objects being drawn to the Render Texture.

  • All of the matrix-style methods have been removed: save, translate, restore, scale, rotate. You can now achieve the same thing by either transforming the object you want to draw to the Render Texture, or using the built-in Camera.

  • You can now crop a Render Texture. Use the setCrop method to define the crop region.

See the fully complete documentation for more details and the extensive examples and tests created.

Text Game Object New Features and Updates

The Text Game Object has been given an internal overhaul to make it more flexible. Some properties have been renamed or moved and new features added:

  • Text can now be cropped in WebGL and Canvas! Use the setCrop method to crop the text.
  • Text now keeps a reference to the renderer in the renderer property.
  • The canvasTexture property has been removed.
  • Text now has internal texture and frame properties. These replace the old canvasTexture but perform the same task, while allowing for texture cropping and much smaller renderer code.

Tile Sprite Object New Features and Updates

The Tile Sprite Game Object has been given an internal overhaul to make it more flexible. Some properties have been renamed or moved and new features added:

  • Tile Sprites can now be cropped in WebGL and Canvas! Use the setCrop method to crop the tile sprite.
  • There is a new method setTileScale which will set the tile scale in a chainable call.
  • There is a new internal canvas property. Tile Sprites work differently than before in Canvas mode: Previously they would use the fillRect command on the game canvas to draw themselves every frame, even if they hadn't changed. They now draw to an internal canvas only when their position or scale changes. This canvas is then drawn to the game canvas instead. It's faster, as it doesn't fillRect every frame and also allows you to draw them to other contexts, such as Render Textures.
  • There are two new internal properties _tilePosition and _tileScale which are Vector 2s that hold the position and scale. Getters have been added, so use the same properties as before in your code.
  • There are two new properties displayTexture and displayFrame. These replace the previous texture and frame properties and hold references to the source texture the Tile Sprite is using.
  • The canvasPattern property has been renamed to fillPattern.
  • The oldFrame property has been removed.
  • The canvasBuffer property has been renamed to fillCanvas.
  • The canvasBufferCtx property has been renamed to fillContext.

New Features

  • Camera.resolution is a new read-only property that holds the current game config resolution that the camera is using. This is used internally for viewport calculations.
  • Text.resolution and the method Text.setResolution allows you to control the resolution of a Static Text Game Object. By default it will be set to match the resolution set in the Game Config, but you can override it yourself via the TextStyle. It allows for much clearer text on High DPI devices, at the cost of larger internal Canvas textures for the Text - so please use with caution, as the more high res Text you have, the more memory it uses up. Fix #3528 (thanks @kirillbunin)
  • TransformMatrix.getCSSMatrix will return a CSS transform matrix formatted string from the current matrix values.
  • CacheManager now creates a new cache called html which is used to store all loaded HTML snippets.
  • FileType.HTML is a new file type loader that will load an HTML snippet and store it in the new html cache. Access it via load.html (this method was previously used to load html to textures, please see load.htmlTexture for this feature now)
  • TransformMatrix.getX is a new method that return the x component from the given x and y values based on the current matrix. This is used heavily in the pipelines.
  • TransformMatrix.getY is a new method that return the y component from the given x and y values based on the current matrix. This is used heavily in the pipelines.
  • TransformMatrix.copyToArray is a new method that will copy the matrix values to the given array. It's the counter-part of copyFromArray.
  • Graphics.setTexture is a new WebGL only method that allows you to set a texture to be used when drawing the shapes on the Graphics object. You can also specify how the texture should be blended with the current fill or gradient colors. Note that the texture is not tiled, it is stretched to fit the shape being drawn.
  • Graphics.fillGradientStyle is a new WebGL only method that allows you to set a gradient for the shapes being filled. You can control the colors at the 4 corners of a rectangle. The colors are then blended automatically in the shader. Use of this feature is limited. For example, you cannot gradient fill a whole path or an arc, as it's made up of lots of triangles. But for quick gradient backgrounds or buttons it's perfect.
  • Graphics.lineGradientStyle is a new WebGL only method that allows you to set a gradient for the shapes being stroked. You can control the colors at the 4 corners of a rectangle. The colors are then blended automatically in the shader. Use of this feature is limited. For example, you cannot gradient stroke a whole path or an arc, as it's made up of lots of triangles. But for quick gradient lines it's perfect.
  • TextureManager.getBase64 is a new method that will take a texture frame key and return a base64 encoded version of the frame. You can also provide the image type and encoder options.
  • Global Plugins now have a new optional data object, the contents of which are passed to the plugins init method. This allows users to pass data directly into a plugin when added in the config: { key: 'BankPlugin', plugin: BankPluginV3, start: true, data: { gold: 5000 } } or when adding a plugin via the install method (thanks @samme)
  • You can now play animations in reverse! Use the new Sprite.anims.playReverse method to play a pre-defined animation in reverse from its starting frame. Or call Sprite.anims.reverse to immediately reverse the flow of an already running animation. Animations running in reverse still count towards the repeat total and respect the yoyo flag (thanks @khaleb85)
  • The ParticleEmitterManager now has the Transform component. This means you can now set the position, rotation or scale of the Emitter Manager, and it will influence every Emitter it is rendering. The Managers transform is mixed with that of the Camera. This works in both Canvas and WebGL.
  • TextureManager.addRenderTexture is a new method that will add a Render Texture into the Texture Manager, allowing you to use it as the texture for Game Objects just by using the texture key. Modifying the source Render Texture will immediately modify any Game Objects using it.
  • TextureSource has a new boolean property isRenderTexture which is set automatically when it's created.
  • The Canvas Renderer has a new method setContext which allows it to swap the context being drawn to by all draw operations. Call the method with no arguments to reset it to the default game canvas.
  • If you set window.FORCE_WEBGL or window.FORCE_CANVAS in the window in which the Phaser game is loaded it will over-ride the renderer type setting in your game config, and force either WebGL or Canvas. This is handy for quickly testing the differences between renderers without having to do a new build each time.
  • TextureSource.source is a new property that contains the original source of the Texture image. It is cleared when the source is destroyed.
  • TransformMatrix.copyToContext is a new method that will copy the values from the Matrix to the given Canvas Rendering Context.
  • Phaser.Utils.String.UUID will return an RFC4122 complaint UUID as a string. This is used internally to avoid cache key conflicts, but is exposed for your own use as well.
  • There is a new Crop Component which is used by non-texture based Game Objects, such as Text and TileSprite. You either use TextureCrop or Crop, not both together on the same object.
  • TransformMatrix.setToContext is a new method that will set the values from the Matrix to the given Canvas Rendering Context using setTransform rather than transform.
  • SetTransform is a new Canvas Renderer function that consolidates the process of preparing a Game Object for rendering, without actually rendering it. This is used internally by the Graphics and Bitmap Text classes.
  • The Texture Manager has a new method called renameTexture which will let you rename a texture, changing the key to the new one given. All existing Game Objects will still maintain their reference, even after a rename.

Updates

  • The Camera class has been split into two: BaseCamera which contains all of the core Camera functions and properties, and would serve as a great base for you to extend for your own custom Cameras, and Camera which is the same name space as previously. Camera extends the Base Camera and adds in follower support and the Special Effects. You don't need to update your code, even if currently extending a Camera, as they work the same as before.
  • Camera.x and Camera.y have been turned into getters / setters, mapped to the internal private values _x and _y respectively. This is so that setting the Camera viewport position directly will now update the new internal resolution calculation vars too.
  • Camera.setScene will now set the Cameras resolution property at the same time and update the internal viewport vars.
  • The Cull Tiles method used by the Dynamic Tilemap Layer has had a nice and significant optimization. It will now use the cull area dimensions to restrict the amount of tile iteration that takes place per layer, resulting in dramatic reductions in processing time on large layers, or multiple layers (thanks @tarsupin)
  • GameObject.willRender now takes a Camera as its only argument and uses it within the check. This has allowed me to remove 23 duplicate checks spread across the various Game Objects, all of which did the same thing, saving both KB and CPU time as the flags were being checked twice in most cases.
  • The file type loader HTML has been renamed to HTMLTexture. If you were using this then please change your calls from load.html to load.htmlTexture. The arguments remain the same.
  • The setBlendMode method in the WebGL Renderer now returns a boolean. True if a new blend mode was set, otherwise false. Previously in returned a reference to the renderer instance.
  • The load.html method has been renamed to load.htmlTexture.
  • The method batchVertices in the TextureTintPipeline has been renamed to batchQuad which more accurately describes what it does.
  • In ArcadePhysics Body.setSize you can now choose to not pass width and height values to the method. If you do this it will check to see if the parent Game Object has a texture frame, and if so, it will use the frame sizes for the Body dimensions (thanks @tarsupin)
  • PluginCache.destroyCorePlugins will remove all core plugins from the cache. Be very careful calling this as Phaser cannot restart or create any new Scenes once this has been called.
  • PluginCache.destroyCustomPlugins will remove all custom plugins from the cache.
  • PluginManager.destroy will now clear all custom plugins from the Plugin Cache. This fixes an issue with not being able to destroy a Phaser game instance and restart it if it used a custom plugin (thanks jd.joshuadavison)
  • Game.destroy has a new boolean argument noReturn. If set it will remove all Core plugins when the game instance is destroyed. You cannot restart Phaser on the same web page after doing this, so only set it if you know you're done and don't need to run Phaser again.
  • The MouseManager will no longer process its native events if the manager reference has been removed (i.e. you move the pointer as the game is destroying itself)
  • The TouchManager will no longer process its native events if the manager reference has been removed (i.e. you move the pointer as the game is destroying itself)
  • Particle.color has been removed as it's now calculated during rendering to allow for Camera alpha support.
  • The Game boot event flow has changed slightly. The Game will now listen for a texturesready event, which is dispatched by the Texture Manager when the default textures have finished processing. Upon receiving this, the Game will emit the ready event, which all the other systems listen for and respond to. The difference is that the Renderer uses the texturesready event to ensure that it is the first thing to be activated, before any other system.
  • The WebGLRenderer has a new property blankTexture which is a reference to an empty 32x32 transparent WebGL Texture. This is used internally for things like rendering Graphics with no texture fills and where no other texture has been set.
  • The WebGLRenderer has a new method setBlankTexture which forces it to set the blank texture as the current texture. This is used after drawing a Render Texture to ensure no other object tries to draw to itself.
  • The StaticTilemapLayer has had the following properties and methods added to it: skipCull, tilesDrawn, tilesTotal, cullPaddingX, cullPaddingY, cullCallback, setSkipCull and setCullPadding as these are all used by the Canvas Static Layer renderer. Static Layers in 3.11 didn't render in Canvas because the cull values were missing, but now render correctly and can also be rendered to other targets, like a Render Texture.
  • The Math.Snap methods Snap.Floor, Snap.Ceil and Snap.To have all gained a new optional boolean argument divide. If set the resulting snapped value will be divided by the gap amount before returning. This is handy if you're trying to quickly snap a value into a grid or array location.
  • The currentBlendMode property has been removed from the Canvas Renderer and is no longer checked by any class. Blend modes are now set directly on the context to avoid state saving invalidation.
  • The currentAlpha property has been removed from the Canvas Renderer and is no longer checked by any class. Alpha values are now set directly on the context to avoid state saving invalidation.
  • TextureCrop and Crop have a new method resetCropObject which generates the crop data object required by Game Objects that support cropping. This allows us to remove duplicate code from a number of Game Objects and replace it with a single function call.
  • The Canvas Renderer has a new batchSprite method that consolidates the process of drawing a texture-based Game Object to the canvas. It processes the alpha, blend mode and matrix calculations in a single function and now is used by nearly all Game Object canvas renderers.
  • The batchTexture method in the Texture Tint Pipeline now supports cropped Game Objects and will adjust the drawn texture frame accordingly.
  • The Matrix Stack Component has been removed. It's no longer used internally and was just wasting space.
  • You can now specify the lineHeight of a Retro Font in the Retro Font Config object (thanks @FelixNemis)
  • When a Static Tilemap Layer is generated in WebGL it will use the Cameras roundPixels value to clamp the tile coordinates.
  • The CanvasRenderer.DrawImage function has been removed, as has the associated drawImage property from the Canvas Renderer as they're no longer used.
  • The CanvasRenderer.BlitImage function has been removed, as has the associated blitImage property from the Canvas Renderer as they're no longer used.
  • You can now access the Game instance directly from a Scene using this.game as long as it exists in the Scene's Injection Map, which it does by default. Be very careful what you do here: there's next to nothing you should actually use this for.
  • Camera.ignore can now take nested-arrays of Game Objects and also supports both Groups and Containers.

Game Config Resolution Specific Bug Fixes

Setting the resolution property in the Game Config to a value other than 1 would cause various errors in the API. The following have been fixed:

  • The game canvas would be sized incorrectly, unless you had enabled auto resizing. It now scales the canvas to the size given, maintaining the resolution. Fix #3468 (thanks @Legomite)
  • Cameras with background colors set would display the filled color area at the wrong size. Camera fills now respect the resolution.
  • The Camera Fade Effect would display the fade fill rectangle at the wrong size. Camera fades now respect the resolution.
  • The Camera Flash Effect would display the fade fill rectangle at the wrong size. Camera flashes now respect the resolution.
  • The Camera Shake Effect would shake the Camera using the wrong width values. Camera Shakes now respect the resolution.
  • Input calculations would not factor in the Game Resolution correctly. If a Camera viewport was not at 0x0 or not the full size, or the Camera was rotated or zoomed, the input areas would be wrong if resolution was > 1. These are now factored in correctly and changing the resolution no longer breaks input. Fix #3606 (thanks @Secretmapper)

Bug Fixes

  • The setCrop method stored its crop object on the prototype chain by mistake, causing all Images or Sprites that were cropped to display the same frame. The crop data has been moved to the Game Object instance, where it should be, fixing this issue (thanks NoxBrutalis)
  • If an AudioFile failed to load and throw an incomplete error, it would cause the console.log to crash JavaScript when trying to log the error. It now only logs the message if it exists. Fix #3830 (thanks @kelostrada)
  • Particles using a blend mode wouldn't render correctly after the updates in 3.11. If the blend mode changes during the processing of an emitter manager it'll now correctly rebind the texture, stopping the particles from vanishing. Fix #3851 (thanks @maxailloud)
  • Adding an array of children to a Group would cause it to mistakenly think you were passing a config object. Fix #3854 (thanks @pedro-w)
  • Graphics paths in WebGL would not render the line join between the final and the first path if the path was closed, leaving a noticeable gap if you used particularly thick strokes. If the path is closed it will now render the final line join properly.
  • If a Mesh caused a batch flush it would fail to render as its texture was lost. It's now rebound correctly after the flush.
  • ArcadePhysics.closest and ArcadePhysics.furthest used the wrong tree reference, causing them to throw errors (thanks @samme)
  • BlitterCanvasRenderer would fail to render a Bob in Canvas mode if it was flipped (thanks @SBCGames)
  • RenderTexture.draw would fail to draw the frame in Canvas mode (thanks @SBCGames)
  • ParticleEmitter would fail to draw a textured particle in Canvas mode (thanks @SBCGames)
  • RenderTexture.preDestroy will now release the canvas back to the CanvasPool if running in canvas mode (thanks @SBCGames)
  • The alpha value is now always set for Render Textures in canvas mode, regardless of the previous alpha value in the renderer (thanks @SBCGames)
  • Zone now calls updateDisplayOrigin in its constructor, causing the displayOriginX and displayOriginY values to now be correct if you create a Zone and then don't resize it. Fix #3865 (thanks @rexrainbow)
  • The CameraManager was accidentally adding extra destroy event calls when a Scene was restarted, causing an Uncaught TypeError: Cannot read property 'events' of null when trying to destroy a game instance having swapped from a Scene to another, and back again. Fix #3878 (thanks @mbunby)
  • RenderTextures in WebGL will now set the viewport size, stopping the console warning in Firefox. Fix #3823 (thanks @SBCGames)
  • Particles now take the Cameras alpha value into consideration when calculating their final alpha values in WebGL. They previously ignored it. If you now alpha a Camera out all particles will change accordingly.
  • The CullTiles updates from 3.11 didn't factor in the position of the Tilemap Layer to its bounds calculations, causing Static layers displayed out of the Camera viewport to never render in Canvas mode. The method has also been optimized further, with less divisions and less checks if culling is disabled.
  • The Particle Emitter when running in Canvas wouldn't allow more than 1 emitter to use a blend mode (as seen in the Electric examples). The blend mode is properly set for each emitter now.
  • The Blend Mode is now set directly in all Canvas Renderers without comparing it to what's stored in the Canvas Renderer. This fixes problems where the blend mode would be lost between two different Game Objects because they restored the context, but didn't update the renderer flag. Game Objects in Canvas can now mix and match blend modes across the display list.
  • Matter.js has received a tiny update that prevents collisionEnd from triggering many times when it should only trigger once (thanks @mikewesthad)
  • Graphics objects couldn't be set to be ignored by Cameras. Now every renderable Game Object can be ignored by a Camera, either directly or via a Container. The exception are Groups because they don't render and are non-exclusive parents.
  • The Tilemap Culling function now uses the Tilemap tile dimensions for its bounds calculations, instead of the layer tile sizes, as they two don't have to match and it's the underlying grid size that takes precedence when calculating visible tiles. Fix #3893 (thanks @Zax37)
  • The Arcade Physics Body.speed property is now set whenever you set the velocity via setVelocity or setVelocityX or setVelocityY which stops the body velocity being reset to zero if useDamping is enabled. Fix #3888 (thanks @samme)

Examples, Documentation and TypeScript

My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:

@SBCGames @rgk @rook2pawn @robbintt @bguyl @halilcakarr @PhaserEditor2D @Edwin222 @tfelix @Yudikubota @hexus @guzmonne @ampled @thanh-taro @dcbriccetti @Dreaded-Gnu

Thanks to @khaleb85 for fixing the super-annoying lag on the API Docs pages when it hung the browser while indexing the search field.

- JavaScript
Published by photonstorm almost 8 years ago