Recent Releases of phaser
phaser - Phaser v4.0.0 Release Candidate 5
New Features
Maskfilter now supportsscaleFactorparameter, 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.Camerahas the new propertyisObjectInversion, used internally to support special transforms for filters.Shaderhas the new methodrenderImmediate, which makes it straightforward to userenderToTexturewhen 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.addandStaticPhysicsGroup.addwill 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.Blockyfilter now has a minimum size of 1, which prevents the object from disappearing.TilemapGPULayernow 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.
DynamicTexturemethodstartCapturenow handles nested parent transforms correctly. This is used inMask, so masks withinContainerobjects should behave correctly too.- Children of filtered
Container/Layerobjects are correctly added to the current camera'srenderList. 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.setRoundedis 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.isRoundedis a new read-only boolean that can be used to determine if the Rectangle Shape Game Object has rounded corners, or not.GameObjects.Rectangle.radiusis a new read-only number that is the size of the rounded corners. Do not set directly, instead use the methodsetRounded.- 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 likePhaser.Math.Angle.ShortestBetween()but in radians.) PR #7092 (thanks @samme) - Added
Phaser.GameObjects.BitmapText#setDisplaySizemethod toBitmapTextto get the original scaled size of 1. PR #6623 (thanks @samme) - Added fallback for Web Audio on Firefox. Firefox doesn't implement
positionX,positionYandpositionZproperties on the AudioListener instances at the moment. This prevents the follow feature from WebAudioSound to operate on Firefox. PR #7083 (thanks @raaaahman)
Updates
- The
EXPANDScale 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.logwas 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.AnimationFramecorrectly uses frame duration when it is set. Fix #7070 (thanks @sylvainpolletvillard)- Particle emitter custom
moveTofunctions can now move particles. Fix #7063 (thanks @samme) - Changed ImageCollections default Tileset values from
nulltoundefined. Fix #7053 (thanks @Snoturky) - Chained tweens now
persistcorrectly even after callingPhaser.Tweens.BaseTween#stop. Fix #7048 (thanks @FranciscoCaetano88) - New left-to-right
TextGame Objects now includes the defaultcanvas.dir = 'ltrandcontext.direction = 'ltr';. Fixes a bug in Chrome 134 & Edge 134 where callingdestroy()on a right-to-leftTextGame Object prevents the next created left-to-rightTextGame Object from rendering. Fix #7077 (thanks @Demeno) GridGame Objects renderslineWidthcorrectly in WebGL mode. Fix #7029 (thanks @AlvaroNeuronup)- Added
collisionMaskandcollisionCategorychecks toPhaser.Physics.Arcade.World#separateto 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
createFromTilesto 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
BatchHandlerQuadSinglerender node added.- This is just a copy of
BatchHandlerQuadwith space for 1 quad. - The rendering system uses this node internally for transferring images in some steps of the filter process.
- This is just a copy of
Changes
BatchHandlerrender 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#genericVertexBufferand#genericVertexDataremoved.- This frees 16MB of RAM and VRAM.
BatchHandlerConfig#createOwnVertexBuffertype property removed.TileSpriteno 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
createFromTilesto 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#vertexRoundModeadded 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 whereroundPixelsis 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 whereroundPixelsis 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.
Blockyfilter 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
WebGLSnapshotand 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.stopListenersandGamepadPlugin.disconnectAllnow 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#renderNodesallows you to add render nodes at game boot.ShaderQuadConfig#initialUniformslets 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 thesetupUniforms()method, where some uniforms might be set redundantly after init. This wrapsShader#renderNode.programManager.setUniform.
Changes
TextureManager#addDynamicTexturenow hasforceEvenparameter.
Fixes
- Fix parent transform on filtered objects (e.g. masks inside containers).
- Fix camera shake.
- Add typedefs for the
{ internal, external }structure ofCamera#filters(andGameObject#filters). - Fix
FilterList#addMaskdocs. - In Layer and Container objects, use that object's children for the
displayListpassed toRenderWebGLSteps. - 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#enableLightingnow 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.YieldContextandRebindContextrender 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
Filtercomponent:setFiltersAutoFocus,setFiltersFocusContext,setFiltersForceComposite,setRenderFilters. - All enhancements from Phaser v3 development have been merged. This includes:
Transform#getWorldPointLayer#getDisplayListDynamicTextureandRenderTexturechanges:forceEvenparameter forces resolution to be divisible by 2.clear(x, y, width, height)method now takes the listed optional parameters.Rectanglenow supports rounded corners.Physics.Matter.Components.Transform#scalefor setting scaleX and scaleY together.WebGLRendererreveals functions around context loss:setExtensionssetContextHandlersdispatchContextLostdispatchContextRestored- Improvements to tile handling for non-orthogonal tiles.
Tween#isNumberTween- Many other fixes and tweaks.
Fixes
- Fix
WebGLSnapshotorientation. - Fix filters rendering outside intended camera scissor area.
- Fix reversion in BitmapText kerning.
- Fix
CaptureFramecompatibility withLayerandContainer. - Fix
Gridusing old methods. It was supposed to use 'stroke' just like otherShapeobjects, not a unique 'outline'. - Add
@returntag toFilterList#addBlend(thanks @phasereditor2d!). - Fix
RenderStepsparameter propagation intoLayerandContainer. This resolves some missing render operations in complex situations. - Fix
DynamicTextureerrors 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.
DrawingContextnow takes screen coordinates, and sets GL coordinates in theWebGLGlobalWrapper.
- 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
RenderWebGLStepto 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
nextTypeMatchfrom Phaser v3, but is much more flexible.
- This takes the place of
- Add
DynamicTexture#capture, for rendering game objects more accurately and with greater control thandraw. - Add
CaptureFramegame object, which copies the current framebuffer to a texture when it renders. This is useful for applying post-processing prior to post.
Fixes
- Prevent
RenderTexturefrom rendering while it's rendering, thus preventing infinite loops. - Fix boundary errors on the Y axis in
TilemapGPULayershader, introduced after switching to GL standard texture orientation. - Fix
Filters#focusFilterssetting camera resolution too late, leading to unexpected results on the first frame. - Fix parent matrix application order, resolving unexpected behavior within Containers.
- Fix
FillCameranode 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#matrixnow includes scroll, and excludes position.Camera#matrixExternalis a new matrix, which includes the position.Camera#matrixCombinedis the multiplication ofmatrixandmatrixExternal. This is sometimes relevant.- The
GetCalcMatrix(src, camera, parentMatrix, ignoreCameraPosition)method now takesignoreCameraPosition, causing its return value to use the identity matrix instead of the camera's position. GetCalcMatrixResultsnow includes amatrixExternalproperty, and factors scroll into thecameraandcalcmatrices.- 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 asspriteMatrix.e -= camera.scrollX * src.scrollFactorXwere 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
SpriteGPULayerefficiently. - Add
SpriteGPULayer#insertMembersmethod. - Add
SpriteGPULayer#insertMembersDatamethod. - Add
SpriteGPULayer#getDataByteSizemethod. - Add non-looping animations to
SpriteGPULayer(set animation toloop: false) to support one-time particle effects and dynamic sources. - Add creation time to
SpriteGPULayermembers. - Add documentation for writing a
Extern#renderfunction. TilemapLayerandTilemapGPULayernow support a parent matrix during rendering.Shapenow setsfiltersFocusContext = trueby default, to prevent clipping stroke off at the edges.
Fixes and Tweaks
- Fix missing reference to Renderer events in
BatchHandler(thanks @mikuso) - Fix
SpriteGPULayersegment handling (segments changed from 32 to 24 to avoid problems with 32-bit number processing) - Allow negative acceleration in
SpriteGPULayermember animations using Gravity. - Rearrange
SpriteGPULayerdata encoding. - Fix
SpriteGPULayerfailing to generate frame animations from config objects. - Allow
TextureSource#setFlipYto affect all textures (except compressed textures, which have fixed orientation). WebGLProgramWrappernow correctly recognizes uniforms with a value ofundefinedand can recognize if they have not changed and do not need updates.- Set
roundPixelsgame option tofalseby 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
DOMElementhas no container. - Fix
TileSpriteapplyingsmoothPixelArtgame option incorrectly.
- JavaScript
Published by photonstorm about 1 year ago
phaser - Phaser v4.0.0 Beta 6
Additions
- Add Filter support to
Layer. - Allow
RenderTextureto 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
roundPixelshandling in many places, mostly by removing it from irrelevant situations.- Remove
TransformMatrix#setQuadparameterroundPixels, as it is no longer used.
- Remove
- Filters are correctly destroyed along with their owners, unless
ignoreDestroyis 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/flipYinFilter#focusFilters. - Fix
BatchHandlerQuad#run()parametertintFill, 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_BOTHfrom working.
- JavaScript
Published by photonstorm over 1 year ago
phaser - Phaser v3.88.1
Bug Fixes
- Fixed
ReferenceError: GetFastValueOp is not definedin NumberTweenBuilder (thanks Flow) - Reverted incorrect change made to
SafeRangearray util function. - Fixed
Array.Utils.GetFirstso 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.getWorldPointis 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.GetFirstcan now search from the end of the array when settingstartIndexto -1.DynamicTextureand by extensionRenderTexturenow have a new boolean propertyforceEvenin their constructor,setSizeandresizemethods. 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 istrueby default. This is a potentially breaking change, so if you know you need an odd sized texture, please set the value tofalse. Fix #6988 (thanks @rexrainbow)
Updates
Tween.isNumberTweenis a new boolean property that tells if the Tween is a NumberTween, or not.- The
TransformMatrix.setTransformmethod 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
mousedownandmouseuphave been added for unlocking Web Audio. Both events occur before aclickevent, 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
addBase64method. Rather than the error "TypeError: null is not an object (evaluating 'texture.source')" is will not return early (thanks @samme) - Both
TweenBuilderandNumberTweenBuilderhave been updated to useGetFastValuefor most properties instead ofGetValue. - The
Transform.getWorldTransformMatrixmethod will now destroy the parent matrix at the end, if it was created within the method. - The Arcade Physics
Body.setGameObjectandStaticBody.setGameObjectmethods 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 thebodyproperty, even if it doesn't exist (converts non-physics objects into physics objects). CallssetSizeto update the body dimensions to make the new Game Object and finally setsenablebased on the given parameter, which is now correctly referenced. The StaticBody version also has a new parameter,enablewhich matches that of the Dynamic Body and defaults totrue(the original state). Fix #6969 (thanks @yongzheng7) - The Arcade Physics
ArcadeColliderTypehas been updated to includePhysics.Arcade.StaticBody. Fix #6967 (thanks @yongzheng7) Phaser.Types.GameObjects.Text.TextStylenow includesletterSpacing: a positive or negative amount to add to the spacing between characters. Fix #7002 (thanks @Stever1388)Tilemaps.Parsers.Tiled.ParseTilesets,Tilemaps.Parsers.Tiled.BuildTilesetIndexandTilemaps.ImageCollection.addImagehave been updated to includewidthandheightof each individual image. Fix #6990 (thanks @stickleprojects)Tilemaps.Components.RenderDebugandTilemaps.Parsers.Tiled.BuildTilesetIndexhave been updated to includewidthandheightoffsets in Image Collections.- Added a warning to
Tilemaps.Components.GetTilesWithinShapewhen attempting to use this method with non orthogonal tilemaps. - Changed the
Cameras.Scene2D.Camera.preRendermethod from protected to public. Fix #7020 (thanks @zoubingwu)
Bug Fixes
TweenData.updatewill 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.durationcan 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.updatecould 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#scalecorrectly scales the physics body with the GameObject. Fix #7001 (thanks @Stever1388)Phaser.Textures.Frame.setCropUVsupdated crop calculation to include thespriteSourceSize. Fix #6996 (thanks @CrispMind)Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiledupdated hexagonal tilemaps to correctly calculate thewidthInPixelsandheightInPixelsbased on the hexagonal overlapping tiles. Fix #6992 (thanks @ptantiku)Phaser.Display.Color.Interpolate.RGBWithRGBnow correctly returns aPhaser.Types.Display.ColorObjectthat includesr,g,b,aandcolorvalues. 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.PluginManagerautomatically boots plugins when the game config render type is set toPhaser.HEADLESS. Fix #6893 (thanks @hubertgrzeskowiak)- Tweens created with
persistset totrueand given acompleteDelayvalue are no longer destroyed and can be replayed. Fix #7008 (thanks @Stever1388) - The
Tweens.TweenChainonStartevent is now dispatched properly. Fix #7007 (thanks @Stever1388) GameObjects.Particles.Zones.DeathZonenow 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.TweenBuilderConfigobject is now correctly executed without errors. Fix #7003 (thanks @Stever1388) - A
GameObjects.Textcreated withwordwrapand withletterSpacingapplied now takes into account the providedletterSpacingvalue to correctly wrap lines. Fix #7002 (thanks @Stever1388) - Creating new
GameObjects.DOMElementsets the GameObject'sdisplayWidthanddisplayHeightusing itsscaleXandscaleYvalues instead of the DOM elementsgetBoundingClientRect()values. Fix #6871 (thanks @HawkenKing) - Setting scale
modetoPhaser.Scale.FITandautoCentertoPhaser.Scale.CENTER_BOTHcorrectly centres canvas on iOS devices. Fix #6862 (thanks @HawkenKing) - On hex maps, creating a blank layer with the
Tilemaps.Tilemap.createBlankLayermethod now correctly sets thehexSideLengthas loaded from the hex tilemap. Fix #6074 (thanks @wwoods) - The
Input.InputPlugin.processDragUpEventnow correctly returnsxandycoordinates in world space. Animations.AnimationState.playmethod now prioritises theframeRateproperty when it is set in thePlayAnimationConfigobject 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
LayerGame Object methodsetToTopwould 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
EmitterOpdefaultEmit()always returnedundefined, causing particle problems if you gave only anonUpdatecallback. Also if you configured an EmitterOp withonEmitoronUpdate, 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
roundPixelsto only operate when objects are axis-aligned and unscaled. This prevents flicker on transforming objects. - Fix
TextureSource.resolutionbeing ignored in WebGL.- This fixes an issue where increasing text resolution increased text size.
- Fix
DynamicTextureusing a camera without the required methods. - Remove
WebGLAttribLocationWrapperas it is unused. - Remove
WebGLRenderer.textureIndexesasglTextureUnits.unitIndicesnow 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,
nearestandfurthest, 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.setQuaddocumentation - 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
FontFileis 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
animproperty 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.updateto achieve the same result with my less repetition. Also fixes an issue where a Tween that used a customeasecallback 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
GetBitmapTextSizethat would lead to incorrect indexes vs. the docs and previous releases (thanks @bagyoni) Utils.String.RemoveAtwould 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.initis 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 theresizemethod.Phaser.GameObjects.Container#tempTransformMatrixhas 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.renderRoundPixelsis a new read-only property that is set during the CamerapreRendermethod 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
renderRoundPixelsboolean 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.resizewill now check theautoResizeproperty 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.MoveAbovefunction didn't recalculate the baseIndex after the splice, meaning the item would end up in the wrong location. - The
HexagonalTileToWorldXYfunction incorrectly usedthisinstead oflayercausing it to error in hex tilemaps with x axis staggering. Fix #6913 (thanks @jummy123) - The
TextGame Object could truncate the length of the Text whensetLetterSpacingwas used. Fix #6915 (thanks @monteiz @rexrainbow) - The
EXPANDScale 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.willResizemethod 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.setExtensionsis 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 theinitand 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.setQuadhas 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 usingroundPixelson 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
wrapmethod has been natively integrated into theBodyclass to replace the existingMatterWrapplugin. Here's how it works. - The Matter
attractorsplugin has been natively integrated into theBodyclass and Matter engine. More details here. - Integrated
MatterCollisionEventsplugin functionality directly into theMatter.Worldclass to handle collisions more effectively. More details here. - Updated
Matter.Worldto improve the performance, accuracy, and reliability of theupdatemethod in handling physics simulations or animations. More details here. - Fixed
Matter.Worldbug wheregroup.lengthreturnsundefined. Changed togroup.getLength()to correctly return number of children in a group. - Calling
Matter.World.pausewould stop the world updating, but the RunnertimeLastTickwasn't reset whenresumewas 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
roundPixelsproperty now defaults tofalse. - The
uRoundPixelsuniform has been removed from the Single, Multi and Mobile vertex shaders. - Setting the
uRoundPixelsuniform 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.roundPixelsvalue to the Transform MatrixsetQuadmethod. - The Multi Pipeline
batchSpriteandbatchTexturemethods will now applyMath.floorto the sprite matrix calculations if camera round pixels is enabled. BaseCamera.preRenderhas been removed. This method was completely overridden byCamera.preRenderwhich 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.preRenderhas been updated to use both zoomX and zoomY for the matrix transform.Camera.preRenderhas 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.maxRetriesis a new Game Config option to set the number of retries a file will attempt to load. The default is 2.LoaderPlugin.maxRetriesis 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.maxRetriesis 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 theLoaderPlugin.maxRetriesproperty.Loader.File.retryAttemptsis 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.isPlayingis 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.dispatchContextLostis a new internal method that is called when the WebGL context is lost. By default this is bound to the propertyWebGLRenderer.contextLostHandler. If you override the context loss handler, be sure to invoke this method in due course.WebGLRenderer.dispatchContextRestoreis a new internal method that is called when the WebGL context is restored. By default this is bound to the propertyWebGLRenderer.contextRestoreHandler. If you override the context restore handler, be sure to invoke this method in due course.WebGLRenderer.setContextHandlersis a new internal method with 2 optional parameters:contextLostandcontextRestored. These allow you to overwrite the defaultcontextLostHandlerandcontextRestoreHandlerhandlers. (thanks @yaustar)Phaser.Textures.Frame#setCutPositionis a new internal method with 2 optional parameters:xandy. These sets the x and y position within the source image to cut from.Phaser.Textures.Frame#setCutSizeis a new internal method with 2 parameters:widthandheight. These sets the width, and height of the area in the source image to cut. (thanks @FelipeIzolan)- Introduced new constants in
ORIENTATION_CONST. The constantsLANDSCAPE_SECONDARYandPORTRAIT_SECONDARYhave been added to thePhaser.Scale.Orientationobject. 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
updateConfigmethod inParticleEmitterto 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#clearmethod. Clear a specific area within aDynamic Textureby specifyingx,y,width, andheightparameters to clear only a portion of the texture. Fix #6853 (thanks @SelfDevTV) - Added functionality to the
Phaser.Renderer.WebGL.RenderTarget#clearmethod. Clear a specific area within theRenderTargetby specifyingx,y,width, andheightparameters. - Added Default Image Handling in
TextureManager. In the gameconfig, setdefaultImagetonullto ignore loading thedefaultImage. - Added Missing Image Handling in
TextureManager. In the gameconfig, setmissingImagetonullto ignore loading themissingImage. - Added White Image Support in
TextureManager. In the gameconfig, setwhiteImagetonullto ignore loading thewhiteImage. Phaser.Core.TimeStep#pauseDurationis a new property that holds the duration of the most recent game pause, if any, in ms (thanks @samme)- The Game
Events#RESUMEevent now contains a new parameterpauseDurationwhich is the duration, in ms, that the game was paused for (thanks @samme) - Added
Phaser.Loader.LoaderPlugin#removePackmethod toLoaderPluginthat removes resources listed in an Asset Pack.(thanks @samme) - When using
Scene.switchyou can now optionally specify adataargument, just like with Scene start, which will be passed along to the Scene that was switched to (thanks @wooseok123) PRE_RENDER_CLEARis 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 theclearBeforeRenderproperty as required, to have fine-grained control over when the canvas is cleared during render.Video.getFirstFrameis 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.getDisplayListis 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.setToTopis a new method that will move the Game Object to the top of the display list, or its parent container (thanks @rexrainbow)GameObject.setToBackis a new method that will move the Game Object to the bottom of the display list, or its parent container (thanks @rexrainbow)GameObject.setAboveis a new method that will move the Game Object to appear above a given Game Object (thanks @rexrainbow)GameObject.setBelowis a new method that will move the Game Object to appear below a given Game Object (thanks @rexrainbow)
WebGL Rendering Updates
WebGLTextureWrapper.updateexpanded:sourceparameter is now type?object, so it can be used for anything that is valid in the constructor.- New
formatparameter can update the texture format.
Updates - Input System
- The
GameObject.disableInteractivemethod has a new optional parameterresetCursor. 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.removeInteractivemethod has a new optional parameterresetCursor. 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.resetCursormethod has a new optional booleanforceResetwhich will reset the state of the CSS canvas cursor, regardless if there is a given Interactive Object, or not. - The
InputPlugin.isActivemethod 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.resetCursoris 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.disablemethod has a new optional boolean parameterresetCursorwhich will reset the CSS custom cursor if true. InputPlugin.setCursoris 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.processMoveEventsInputPlugin.processWheelEventInputPlugin.processOverEventsInputPlugin.processOutEventsInputPlugin.processOverOutEventsInputPlugin.processUpEventsInputPlugin.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.forceDownStateis 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.forceUpStateis 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.forceOverStateis 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.forceOutStateis 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.forceStateis a new internal method that forces a Game Object into the given state.
Updates
- Added
Phaser.Scale.ScaleManager.leaveFullScreenSuccessHandlermethod to separateEvents.LEAVE_FULLSCREENfromPhaser.Scale.ScaleManager.stopFullscreento ensureEvents.LEAVE_FULLSCREENis only emitted once when exiting fullscreen mode. (Fix #6885, thanks @Antriel) - Calling
Timeline.pausewill now pause any currently active Tweens that the Timeline had started (thanks @monteiz) - Calling
Timeline.resumewill now resume any currently paused Tweens that the Timeline had started (thanks @monteiz) - Calling
Timeline.clearandTimeline.destroywill now destroy any currently active Tweens that the Timeline had created. Previously, active tweens would continue to play to completion (thanks @monteiz) TimelineEventhas a new property calledtweenInstance. 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
requestVideoFramepolyfill has been updated to the latest release, which should resolve some SSR framework issues. Fix #6776 (thanks @lantictac) ScaleManagerlisteners includes checks for thescreen.orientationobject and adds/removes achangeeventListener method to handle screen orientation changes on mobile devices. Theorientationchangeevent is still maintained for backwards compatibility. Fix #6837 (thanks @rexrainbow)- When creating a new
TileSprite, setting eitherwidthorheightto0results in both values being set to thedisplayFrame.widthanddisplayFrame.height. The updated logic now checks forwidthandheightseparately. Ifwidthis0, it is set todisplayFrame.width. Ifheightis0, it is set todisplayFrame.height. Fix #6857 (thanks @GaryStanton) - Updated
GetBitmapTextSizewith improvedmaxWidthcalculations for wrapped text. Vector3.subVectorsis 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.setStylemethod will no longer mutate the givenstyleobject if it includes a numericfontSizevalue. Fix #6863 (thanks @stormpanda) - Calling the
Shape.Ellipse.setSizemethod will internally callupdateDisplayOriginto retain position after a size change. - The
BitmapText BatchCharfunction now inlines all of the matrix math, avoiding 16 function calls per character rendered.
Bug Fixes
- The
activePointersgame config option is now the correct amount of touch input pointers set. Fix #6783 (thanks @samme) - The method
TextureManager.checkKeywill now returnfalseif 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
EXPANDscale 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 returnsnull. Fix #6799 (thanks @samme) - Calling the Arcade Body
setPushable(false)method forcirclebodies prevents the bodies from being pushed. Fix #5617 (thanks @kainage) - Calling
addDeathZone()on a particle emitter Game Object had a bug where theDeathZoneused world position coordinates.DeathZonenow uses local position coordinates following the particle emitter position. Fix #6371 (thanks @vforsh) - Updated the
GetLineToLinemethod inGetLineToLineto handle the case wheredx1ordy1values is zero. This ensures the function correctly returnsnullin 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 betweenbody1.collisionMaskandbody2.collisionCategory. The defaultcollisionMaskvalue is changed to2147483647to correctly match anycollisionCategory. Fix #6764 (thanks @codeimpossible) - Resolved an issue in
BitmapTextwhere 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
BitmapTextwhere an extra empty line was added whensetMaxWidthwas called, and the width of the line was less than a word. Previously,yAdvancewas incorrectly incremented bylineHeight + lineSpacingfor each word, leading to an unintended increase in vertical space. The correction now calculatesyAdvancebased on thecurrentLineindex, ensuring that vertical spacing accurately reflects the number of lines. Fix #6807 (thanks @AlvaroNeuronup) - Resolved an issue in
BitmapTextwhere adding a space character' 'at the end of a line caused the following line of to ignore line wrapping when usingsetMaxWidth. Fix #6860 (thanks @bagyoni) - The
Matrix4.lookAtRHmethod would fail because it called two missing Vector3 methods. - The
RenderTargetwill now automatically listen for the Renderer resize event ifautoResizeis 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.getFrameBoundsmethod 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 viaload.spritesheetinstead ofload.imagewould have its margin and spacing ignored. Fix #6823 (thanks @damian-pastorini) - If you used letter spacing on a
TextGame 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.batchQuadmethod will now applyMath.roundto the target bounds center point. This prevents sub-pixel values during thecopyTextSubImage2Dcall, 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
processCallbackwill now correctly handle non-Game Object physics bodies and pass them to the callback (thanks @ospira) - If you set a
WebAudioSoundto loop and setSoundManager.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
MeshWebGLRenderer will now recalculate thevertexOffsetcorrectly 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
NineSliceGame Object will now guard against an invalid texture by checking for theframeandtextureFramevars 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.leftButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.rightButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.middleButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.backButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.forwardButtonReleasedwill now returntruewhen 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.Mapand replacing it with a regular JSMapinstance. This means methods likecontainsandsetAllwill be gone. - We are removing
Phaser.Struct.Setand replacing it with a regular JSSetinstance. This means methods likeiterateLocalwill be gone. - The
Create.GenerateTexture, all of the Create Palettes and thecreatefolder will be removed. - The
phaser-ie9.jsentry-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.Pointclass 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
wrapmethod has been natively integrated into theBodyclass to replace the existingMatterWrapplugin. Here's how it works. - The Matter
attractorsplugin has been natively integrated into theBodyclass and Matter engine. More details here. - Integrated
MatterCollisionEventsplugin functionality directly into theMatter.Worldclass to handle collisions more effectively. More details here. - Updated
Matter.Worldto improve the performance, accuracy, and reliability of theupdatemethod in handling physics simulations or animations. More details here. - Fixed
Matter.Worldbug wheregroup.lengthreturnsundefined. Changed togroup.getLength()to correctly return number of children in a group. - Calling
Matter.World.pausewould stop the world updating, but the RunnertimeLastTickwasn't reset whenresumewas 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
roundPixelsproperty now defaults tofalse. - The
uRoundPixelsuniform has been removed from the Single, Multi and Mobile vertex shaders. - Setting the
uRoundPixelsuniform 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.roundPixelsvalue to the Transform MatrixsetQuadmethod. - The Multi Pipeline
batchSpriteandbatchTexturemethods will now applyMath.floorto the sprite matrix calculations if camera round pixels is enabled. BaseCamera.preRenderhas been removed. This method was completely overridden byCamera.preRenderwhich 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.preRenderhas been updated to use both zoomX and zoomY for the matrix transform.Camera.preRenderhas 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.maxRetriesis a new Game Config option to set the number of retries a file will attempt to load. The default is 2.LoaderPlugin.maxRetriesis 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.maxRetriesis 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 theLoaderPlugin.maxRetriesproperty.Loader.File.retryAttemptsis 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.isPlayingis 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.dispatchContextLostis a new internal method that is called when the WebGL context is lost. By default this is bound to the propertyWebGLRenderer.contextLostHandler. If you override the context loss handler, be sure to invoke this method in due course.WebGLRenderer.dispatchContextRestoreis a new internal method that is called when the WebGL context is restored. By default this is bound to the propertyWebGLRenderer.contextRestoreHandler. If you override the context restore handler, be sure to invoke this method in due course.WebGLRenderer.setContextHandlersis a new internal method with 2 optional parameters:contextLostandcontextRestored. These allow you to overwrite the defaultcontextLostHandlerandcontextRestoreHandlerhandlers. (thanks @yaustar)Phaser.Textures.Frame#setCutPositionis a new internal method with 2 optional parameters:xandy. These sets the x and y position within the source image to cut from.Phaser.Textures.Frame#setCutSizeis a new internal method with 2 parameters:widthandheight. These sets the width, and height of the area in the source image to cut. (thanks @FelipeIzolan)- Introduced new constants in
ORIENTATION_CONST. The constantsLANDSCAPE_SECONDARYandPORTRAIT_SECONDARYhave been added to thePhaser.Scale.Orientationobject. 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
updateConfigmethod inParticleEmitterto 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#clearmethod. Clear a specific area within aDynamic Textureby specifyingx,y,width, andheightparameters to clear only a portion of the texture. Fix #6853 (thanks @SelfDevTV) - Added functionality to the
Phaser.Renderer.WebGL.RenderTarget#clearmethod. Clear a specific area within theRenderTargetby specifyingx,y,width, andheightparameters. - Added Default Image Handling in
TextureManager. In the gameconfig, setdefaultImagetonullto ignore loading thedefaultImage. - Added Missing Image Handling in
TextureManager. In the gameconfig, setmissingImagetonullto ignore loading themissingImage. - Added White Image Support in
TextureManager. In the gameconfig, setwhiteImagetonullto ignore loading thewhiteImage. Phaser.Core.TimeStep#pauseDurationis a new property that holds the duration of the most recent game pause, if any, in ms (thanks @samme)- The Game
Events#RESUMEevent now contains a new parameterpauseDurationwhich is the duration, in ms, that the game was paused for (thanks @samme) - Added
Phaser.Loader.LoaderPlugin#removePackmethod toLoaderPluginthat removes resources listed in an Asset Pack.(thanks @samme) - When using
Scene.switchyou can now optionally specify adataargument, just like with Scene start, which will be passed along to the Scene that was switched to (thanks @wooseok123) PRE_RENDER_CLEARis 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 theclearBeforeRenderproperty as required, to have fine-grained control over when the canvas is cleared during render.Video.getFirstFrameis 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.getDisplayListis 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.setToTopis a new method that will move the Game Object to the top of the display list, or its parent container (thanks @rexrainbow)GameObject.setToBackis a new method that will move the Game Object to the bottom of the display list, or its parent container (thanks @rexrainbow)GameObject.setAboveis a new method that will move the Game Object to appear above a given Game Object (thanks @rexrainbow)GameObject.setBelowis a new method that will move the Game Object to appear below a given Game Object (thanks @rexrainbow)
WebGL Rendering Updates
WebGLTextureWrapper.updateexpanded:sourceparameter is now type?object, so it can be used for anything that is valid in the constructor.- New
formatparameter can update the texture format.
Updates - Input System
- The
GameObject.disableInteractivemethod has a new optional parameterresetCursor. 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.removeInteractivemethod has a new optional parameterresetCursor. 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.resetCursormethod has a new optional booleanforceResetwhich will reset the state of the CSS canvas cursor, regardless if there is a given Interactive Object, or not. - The
InputPlugin.isActivemethod 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.resetCursoris 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.disablemethod has a new optional boolean parameterresetCursorwhich will reset the CSS custom cursor if true. InputPlugin.setCursoris 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.processMoveEventsInputPlugin.processWheelEventInputPlugin.processOverEventsInputPlugin.processOutEventsInputPlugin.processOverOutEventsInputPlugin.processUpEventsInputPlugin.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.forceDownStateis 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.forceUpStateis 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.forceOverStateis 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.forceOutStateis 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.forceStateis a new internal method that forces a Game Object into the given state.
Updates
- Added
Phaser.Scale.ScaleManager.leaveFullScreenSuccessHandlermethod to separateEvents.LEAVE_FULLSCREENfromPhaser.Scale.ScaleManager.stopFullscreento ensureEvents.LEAVE_FULLSCREENis only emitted once when exiting fullscreen mode. (Fix #6885, thanks @Antriel) - Calling
Timeline.pausewill now pause any currently active Tweens that the Timeline had started (thanks @monteiz) - Calling
Timeline.resumewill now resume any currently paused Tweens that the Timeline had started (thanks @monteiz) - Calling
Timeline.clearandTimeline.destroywill now destroy any currently active Tweens that the Timeline had created. Previously, active tweens would continue to play to completion (thanks @monteiz) TimelineEventhas a new property calledtweenInstance. 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
requestVideoFramepolyfill has been updated to the latest release, which should resolve some SSR framework issues. Fix #6776 (thanks @lantictac) ScaleManagerlisteners includes checks for thescreen.orientationobject and adds/removes achangeeventListener method to handle screen orientation changes on mobile devices. Theorientationchangeevent is still maintained for backwards compatibility. Fix #6837 (thanks @rexrainbow)- When creating a new
TileSprite, setting eitherwidthorheightto0results in both values being set to thedisplayFrame.widthanddisplayFrame.height. The updated logic now checks forwidthandheightseparately. Ifwidthis0, it is set todisplayFrame.width. Ifheightis0, it is set todisplayFrame.height. Fix #6857 (thanks @GaryStanton) - Updated
GetBitmapTextSizewith improvedmaxWidthcalculations for wrapped text. Vector3.subVectorsis 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.setStylemethod will no longer mutate the givenstyleobject if it includes a numericfontSizevalue. Fix #6863 (thanks @stormpanda) - Calling the
Shape.Ellipse.setSizemethod will internally callupdateDisplayOriginto retain position after a size change. - The
BitmapText BatchCharfunction now inlines all of the matrix math, avoiding 16 function calls per character rendered.
Bug Fixes
- The
activePointersgame config option is now the correct amount of touch input pointers set. Fix #6783 (thanks @samme) - The method
TextureManager.checkKeywill now returnfalseif 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
EXPANDscale 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 returnsnull. Fix #6799 (thanks @samme) - Calling the Arcade Body
setPushable(false)method forcirclebodies prevents the bodies from being pushed. Fix #5617 (thanks @kainage) - Calling
addDeathZone()on a particle emitter Game Object had a bug where theDeathZoneused world position coordinates.DeathZonenow uses local position coordinates following the particle emitter position. Fix #6371 (thanks @vforsh) - Updated the
GetLineToLinemethod inGetLineToLineto handle the case wheredx1ordy1values is zero. This ensures the function correctly returnsnullin 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 betweenbody1.collisionMaskandbody2.collisionCategory. The defaultcollisionMaskvalue is changed to2147483647to correctly match anycollisionCategory. Fix #6764 (thanks @codeimpossible) - Resolved an issue in
BitmapTextwhere 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
BitmapTextwhere an extra empty line was added whensetMaxWidthwas called, and the width of the line was less than a word. Previously,yAdvancewas incorrectly incremented bylineHeight + lineSpacingfor each word, leading to an unintended increase in vertical space. The correction now calculatesyAdvancebased on thecurrentLineindex, ensuring that vertical spacing accurately reflects the number of lines. Fix #6807 (thanks @AlvaroNeuronup) - Resolved an issue in
BitmapTextwhere adding a space character' 'at the end of a line caused the following line of to ignore line wrapping when usingsetMaxWidth. Fix #6860 (thanks @bagyoni) - The
Matrix4.lookAtRHmethod would fail because it called two missing Vector3 methods. - The
RenderTargetwill now automatically listen for the Renderer resize event ifautoResizeis 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.getFrameBoundsmethod 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 viaload.spritesheetinstead ofload.imagewould have its margin and spacing ignored. Fix #6823 (thanks @damian-pastorini) - If you used letter spacing on a
TextGame 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.batchQuadmethod will now applyMath.roundto the target bounds center point. This prevents sub-pixel values during thecopyTextSubImage2Dcall, 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
processCallbackwill now correctly handle non-Game Object physics bodies and pass them to the callback (thanks @ospira) - If you set a
WebAudioSoundto loop and setSoundManager.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
MeshWebGLRenderer will now recalculate thevertexOffsetcorrectly 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
NineSliceGame Object will now guard against an invalid texture by checking for theframeandtextureFramevars 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.leftButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.rightButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.middleButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.backButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.forwardButtonReleasedwill now returntruewhen 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.Mapand replacing it with a regular JSMapinstance. This means methods likecontainsandsetAllwill be gone. - We are removing
Phaser.Struct.Setand replacing it with a regular JSSetinstance. This means methods likeiterateLocalwill be gone. - The
Create.GenerateTexture, all of the Create Palettes and thecreatefolder will be removed. - The
phaser-ie9.jsentry-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.Pointclass 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
roundPixelsproperty now defaults tofalse. - The
uRoundPixelsuniform has been removed from the Single, Multi and Mobile vertex shaders. - Setting the
uRoundPixelsuniform 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.roundPixelsvalue to the Transform MatrixsetQuadmethod. - The Multi Pipeline
batchSpriteandbatchTexturemethods will now applyMath.floorto the sprite matrix calculations if camera round pixels is enabled. BaseCamera.preRenderhas been removed. This method was completely overridden byCamera.preRenderwhich 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.preRenderhas been updated to use both zoomX and zoomY for the matrix transform.Camera.preRenderhas 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.isPlayingis 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.dispatchContextLostis a new internal method that is called when the WebGL context is lost. By default this is bound to the propertyWebGLRenderer.contextLostHandler. If you override the context loss handler, be sure to invoke this method in due course.WebGLRenderer.dispatchContextRestoreis a new internal method that is called when the WebGL context is restored. By default this is bound to the propertyWebGLRenderer.contextRestoreHandler. If you override the context restore handler, be sure to invoke this method in due course.WebGLRenderer.setContextHandlersis a new internal method with 2 optional parameters:contextLostandcontextRestored. These allow you to overwrite the defaultcontextLostHandlerandcontextRestoreHandlerhandlers. (thanks @yaustar)Phaser.Textures.Frame#setCutPositionis a new internal method with 2 optional parameters:xandy. These sets the x and y position within the source image to cut from.Phaser.Textures.Frame#setCutSizeis a new internal method with 2 parameters:widthandheight. These sets the width, and height of the area in the source image to cut. (thanks @FelipeIzolan)- Introduced new constants in
ORIENTATION_CONST. The constantsLANDSCAPE_SECONDARYandPORTRAIT_SECONDARYhave been added to thePhaser.Scale.Orientationobject. 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
updateConfigmethod inParticleEmitterto 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
wrapmethod has been natively integrated into theBodyclass to replace the existingMatterWrapplugin. Here's how it works. - The Matter
attractorsplugin has been natively integrated into theBodyclass and Matter engine. More details here. - Added functionality to the
Phaser.Textures.DynamicTexture#clearmethod. Clear a specific area within aDynamic Textureby specifyingx,y,width, andheightparameters to clear only a portion of the texture. Fix #6853 (thanks @SelfDevTV) - Added functionality to the
Phaser.Renderer.WebGL.RenderTarget#clearmethod. Clear a specific area within theRenderTargetby specifyingx,y,width, andheightparameters. - Added Default Image Handling in
TextureManager. In the gameconfig, setdefaultImagetonullto ignore loading thedefaultImage. - Added Missing Image Handling in
TextureManager. In the gameconfig, setmissingImagetonullto ignore loading themissingImage. - Added White Image Support in
TextureManager. In the gameconfig, setwhiteImagetonullto ignore loading thewhiteImage. Phaser.Core.TimeStep#pauseDurationis a new property that holds the duration of the most recent game pause, if any, in ms (thanks @samme)- The Game
Events#RESUMEevent now contains a new parameterpauseDurationwhich is the duration, in ms, that the game was paused for (thanks @samme) - Added
Phaser.Loader.LoaderPlugin#removePackmethod toLoaderPluginthat removes resources listed in an Asset Pack.(thanks @samme)
WebGL Rendering Updates
WebGLTextureWrapper.updateexpanded:sourceparameter is now type?object, so it can be used for anything that is valid in the constructor.- New
formatparameter can update the texture format.
Updates
- MatterJS updated to 0.20.0 and integrated into Phaser. Here are details about the update.
- Integrated
MatterCollisionEventsplugin functionality directly into theMatter.Worldclass to handle collisions more effectively. More details here. - Updated
Matter.Worldto improve the performance, accuracy, and reliability of theupdatemethod in handling physics simulations or animations. More details here. - Calling
Timeline.pausewill now pause any currently active Tweens that the Timeline had started (thanks @monteiz) - Calling
Timeline.resumewill now resume any currently paused Tweens that the Timeline had started (thanks @monteiz) - Calling
Timeline.clearandTimeline.destroywill now destroy any currently active Tweens that the Timeline had created. Previously, active tweens would continue to play to completion (thanks @monteiz) TimelineEventhas a new property calledtweenInstance. 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
requestVideoFramepolyfill has been updated to the latest release, which should resolve some SSR framework issues. Fix #6776 (thanks @lantictac) ScaleManagerlisteners includes checks for thescreen.orientationobject and adds/removes achangeeventListener method to handle screen orientation changes on mobile devices. Theorientationchangeevent is still maintained for backwards compatibility. Fix #6837 (thanks @rexrainbow)- When creating a new
TileSprite, setting eitherwidthorheightto0results in both values being set to thedisplayFrame.widthanddisplayFrame.height. The updated logic now checks forwidthandheightseparately. Ifwidthis0, it is set todisplayFrame.width. Ifheightis0, it is set todisplayFrame.height. Fix #6857 (thanks @GaryStanton) - Updated
GetBitmapTextSizewith improvedmaxWidthcalculations for wrapped text. Vector3.subVectorsis 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.setStylemethod will no longer mutate the givenstyleobject if it includes a numericfontSizevalue. Fix #6863 (thanks @stormpanda) - Calling the
Shape.Ellipse.setSizemethod will internally callupdateDisplayOriginto retain position after a size change. - The
BitmapText BatchCharfunction now inlines all of the matrix math, avoiding 16 function calls per character rendered.
Bug Fixes
- The
activePointersgame config option is now the correct amount of touch input pointers set. Fix #6783 (thanks @samme) - The method
TextureManager.checkKeywill now returnfalseif 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
EXPANDscale 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 returnsnull. Fix #6799 (thanks @samme) - Calling the Arcade Body
setPushable(false)method forcirclebodies prevents the bodies from being pushed. Fix #5617 (thanks @kainage) - Calling
addDeathZone()on a particle emitter Game Object had a bug where theDeathZoneused world position coordinates.DeathZonenow uses local position coordinates following the particle emitter position. Fix #6371 (thanks @vforsh) - Updated the
GetLineToLinemethod inGetLineToLineto handle the case wheredx1ordy1values is zero. This ensures the function correctly returnsnullin 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.Worldbug wheregroup.lengthreturnsundefined. Changed togroup.getLength()to correctly return number of children in a group. - Fixed Group vs Group collisions failing when performing a bitwise
&operation betweenbody1.collisionMaskandbody2.collisionCategory. The defaultcollisionMaskvalue is changed to2147483647to correctly match anycollisionCategory. Fix #6764 (thanks @codeimpossible) - Resolved an issue in
BitmapTextwhere 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
BitmapTextwhere an extra empty line was added whensetMaxWidthwas called, and the width of the line was less than a word. Previously,yAdvancewas incorrectly incremented bylineHeight + lineSpacingfor each word, leading to an unintended increase in vertical space. The correction now calculatesyAdvancebased on thecurrentLineindex, ensuring that vertical spacing accurately reflects the number of lines. Fix #6807 (thanks @AlvaroNeuronup) - Resolved an issue in
BitmapTextwhere adding a space character' 'at the end of a line caused the following line of to ignore line wrapping when usingsetMaxWidth. Fix #6860 (thanks @bagyoni) - The
Matrix4.lookAtRHmethod would fail because it called two missing Vector3 methods. - The
RenderTargetwill now automatically listen for the Renderer resize event ifautoResizeis true. This fixes an issue with Bitmap Masks where they wouldn't resize if the renderer resized. Fix #6769 (thanks @pavels) - The
Texture.getFrameBoundsmethod 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 viaload.spritesheetinstead ofload.imagewould have its margin and spacing ignored. Fix #6823 (thanks @damian-pastorini)
Input Bug Fixes
- The method
pointer.leftButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.rightButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.middleButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.backButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.forwardButtonReleasedwill now returntruewhen 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.Mapand replacing it with a regular JSMapinstance. This means methods likecontainsandsetAllwill be gone. - We are removing
Phaser.Struct.Setand replacing it with a regular JSSetinstance. This means methods likeiterateLocalwill be gone. - The
Create.GenerateTexture, all of the Create Palettes and thecreatefolder will be removed. - The
phaser-ie9.jsentry-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.isPlayingis 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.dispatchContextLostis a new internal method that is called when the WebGL context is lost. By default this is bound to the propertyWebGLRenderer.contextLostHandler. If you override the context loss handler, be sure to invoke this method in due course.WebGLRenderer.dispatchContextRestoreis a new internal method that is called when the WebGL context is restored. By default this is bound to the propertyWebGLRenderer.contextRestoreHandler. If you override the context restore handler, be sure to invoke this method in due course.WebGLRenderer.setContextHandlersis a new internal method with 2 optional parameters:contextLostandcontextRestored. These allow you to overwrite the defaultcontextLostHandlerandcontextRestoreHandlerhandlers. (thanks @yaustar)Phaser.Textures.Frame#setCutPositionis a new internal method with 2 optional parameters:xandy. These sets the x and y position within the source image to cut from.Phaser.Textures.Frame#setCutSizeis a new internal method with 2 parameters:widthandheight. 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 constantsLANDSCAPE_SECONDARYandPORTRAIT_SECONDARYhave been added to thePhaser.Scale.Orientationobject. 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.updateexpanded:sourceparameter is now type?object, so it can be used for anything that is valid in the constructor.- New
formatparameter can update the texture format.
Updates
- Calling
Timeline.pausewill now pause any currently active Tweens that the Timeline had started (thanks @monteiz) - Calling
Timeline.resumewill now resume any currently paused Tweens that the Timeline had started (thanks @monteiz) - Calling
Timeline.clearandTimeline.destroywill now destroy any currently active Tweens that the Timeline had created. Previously, active tweens would continue to play to completion (thanks @monteiz) TimelineEventhas a new property calledtweenInstance. 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
requestVideoFramepolyfill has been updated to the latest release, which should resolve some SSR framework issues. Fix #6776 (thanks @lantictac) ScaleManagerlisteners includes checks for thescreen.orientationobject and adds/removes achangeeventListener method to handle screen orientation changes on mobile devices. Theorientationchangeevent is still maintained for backwards compatibility. Fix #6837 (thanks @rexrainbow)
Bug Fixes
- The
activePointersgame config option is now the correct amount of touch input pointers set. Fix #6783 (thanks @samme) - The method
TextureManager.checkKeywill now returnfalseif 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
EXPANDscale 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 returnsnull. Fix #6799 (thanks @samme) - Calling the Arcade Body
setPushable(false)method forcirclebodies prevents the bodies from being pushed. Fix #5617 (thanks @kainage) - Calling
addDeathZone()on a particle emitter Game Object had a bug where theDeathZoneused world position coordinates.DeathZonenow uses local position coordinates following the particle emitter position. Fix #6371 (thanks @vforsh) - Updated the
GetLineToLinemethod inGetLineToLine.jsto handle the case wheredx1ordy1values is zero. This ensures the function correctly returnsnullin 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.jswhere an extra empty line was added whensetMaxWidthwas called, and the width of the line was less than a word. Previously,yAdvancewas incorrectly incremented bylineHeight + lineSpacingfor each word, leading to an unintended increase in vertical space. The correction now calculatesyAdvancebased on thecurrentLineindex, ensuring that vertical spacing accurately reflects the number of lines. Fix #6807 (thanks @AlvaroNeuronup)
Input Bug Fixes
- The method
pointer.leftButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.rightButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.middleButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.backButtonReleasedwill now returntruewhen multiple mouse buttons are being pressed. - The method
pointer.forwardButtonReleasedwill now returntruewhen 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.Mapand replacing it with a regular JSMapinstance. This means methods likecontainsandsetAllwill be gone. - We are removing
Phaser.Struct.Setand replacing it with a regular JSSetinstance. This means methods likeiterateLocalwill be gone. - The
Create.GenerateTexture, all of the Create Palettes and thecreatefolder will be removed. - The
phaser-ie9.jsentry-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
RenderTexturecrashing 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.setFlipYalways updates the texture. - Remove unsynced
flipYfrom render textures inShaderandDynamicTexture. - Reverted a change made in
TouchManagerthat would prevent clicks from outside the game window from being registered. Fix #6747 (thanks @ulsoftnaver @jaxtheking)
Updates
- Modified
onMouseUpWindowandonMouseDownWindowin theMouseManagerso they now check forsourceCapabilities.firesTouchEventsand 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.base64is a new read-only boolean property that is set if the file contains a Data URI encoded string.Loader.File.onBase64Loadis a new method that is called when the file has finished decoding from a Data URI.- The
ImageFilewill now default to using the Image Load Element if a base64 file is detected, instead of throwing a console warning about unsupported types. - The
XHRLoaderwill 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.setSnapis 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#snapWidthandConfig#snapHeightare new properties in the Game Config that hold the parsedsnapconfig 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.createFromTilesmethod has been updated. It will now copy the following properties, if set in the Tile, to the Sprites it creates:rotation,flipX,flipY,alpha,visibleandtint. If these properties are declared in thespriteConfigpassed to the method, those will be used instead, otherwise the Tile values are used. Fix #6711 (thanks @Nerodon) - The
Tilemap.createFromTilesmethod has a new property calleduseSpriteSheet. If this is set totrueand 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 anoriginin the spriteConfig, it will adjust the sprite positions by half the tile size, to position them accurately on the map. Texture#getFrameBoundsis 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.RectangleLikeis a new typedef that defines a rectangle-like object with publicx,y,widthandheightproperties.
WebGL Renderer Updates
- Fix MIPmap filters being effectively disabled for compressed textures.
WebGLRenderer.getCompressedTexturescan 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
S3TCRGBtoS3TCSRGBinWebGLTextureCompression,CompressedTextureFileConfig, andFileConfigtypedefs. - Fix generating spritesheets from members of texture atlases based on compressed textures (thanks @vladyslavfolkuian)
- The
BloomFXandBlurFXand any custom pipeline that relies on using theUtilityPipelinefull or half frame targets will now correctly draw even after the renderer size changes. Fix #6677 (thanks @Nerodon) - The
PostFXPipeline.postBatchmethod 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
mipmapFilterset. Fix #6721 (thanks @saintflow and @rexrainbow) - The
UtilityPipelinenow setsautoResizetotruein its Render Target Config, so that the globalfullFrameandhalfFrameRender Targets will automatically resize if the renderer changes. WebGLPipeline.resizeUniformis a new property that is defined in theWebGLPipelineConfig. This is a string that defines auResolutionproperty, 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
preUpdateautomatically when theplaymethod 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.setSlotAlphais a new method that allows you to set the alpha on a specific slot in a Spine skeleton.- The
SpineGameObject.setAlphamethod 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 newsetSlotAlphamethod instead. Fix #6571 (thanks @spayton) - The
SpineFile.onFileCompletehandler was running a regular expression againstfile.srcinstead offile.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)
Meshbased Game Objects now can use an input config with thesetInteractivemethod, which supports the optionsdraggable,dropzone,cursoranduserHandCursor. Fix #6510 #6652 (thanks @Baegus @Neppord)- The touch event handler
onTouchEndWindownow stops pointer events when clicking through DOM elements to input. Fix #6697 (thanks @laineus) - The
Input.InputPluginmethoddisablewhich is called byGameObjects.GameObject#disableInteractivekeeps its temp hit box value which stops propagation to interactive Game Objects in another scene. Fix #6601 (thanks @UnaiNeuronUp) - Using
setInteractiveandremoveInteractivemethods of a Game Object outside of the game loop would cause an error in whichInput.InputManager#resetCursorwould lose input context. Fix #6387 (thanks @TomorrowToday)
Updates
- The
TweenChainBuilderwas incorrectly setting thepersistflag on the Chain totrue, which goes against what the documentation says. It now correctly sets it tofalse. 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
droppedargument has now been added to the documentation for theDRAG_ENDandGAMEOBJECT_DRAG_ENDevents. (thanks @samme) Container.onChildDestroyedis 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
TextandTileSpriteGame Objects now place their textures into the globalTextureManagerand a_textureKeyprivate string property has been added which contains a UUID to reference that texture. - The
Tilemaps.Components.WeightedRandomizemethod now uses the PhaserMath.RND.fracmethod with a seed instead of theMath.Randomstatic method. (thanks @jorbascrumps) Tilemaps.Components.IsometricCullTilesdoes theCheckIsoBoundsmethod check last when building the outputArray, as to help optimize in situations where the tile would not be visible anyway. (thanks @zegenie)Tilemaps.Components.WeightedRandomizenow uses the PhaserMath.RND.fracmethod with a seed instead theMath.Randomstatic method. (thanks @jorbascrumps)- The
LayerGame Object has had itsremoveAll,removeandaddmethods removed. These methods are all still available via theListclass that Layer inherits, but thedestroyChildparameters are no longer available. - The
Renderer.CanvasandRenderer.WebGLwill now only be included in the build file if the corresponding feature flagsCANVAS_RENDERERand/orWEBGL_RENDERERare set totrue. For Canvas only builds this saves a lot of space in the build. (thanks @samme) - You can now specify an
autoResizeboolean in theRenderTargetConfigwhich is passed to the Render Targets when they are created by a pipeline. - The
ActionsmethodPlaceOnLinenow has an addedeaseparameter which accepts a string from the EaseMap or a custom ease function to allow for different distributions along a line. (thanks @sB3p) - The
XHRLoaderwill now listen forontimeoutand if triggered it will hand over to theFile.onErrorhandler. This prevents the Loader from stalling if a file times out. Fix #6472 (thanks @343dev) LightPipeline.currentNormalMapwas incorrectly documented as being a property ofWebGLRenderer.- The
VideoGame Object now emits ametadataevent, which emits once the video metadata is available. - The
Time.Timelineclass now supports looping via therepeatmethod.Types.Time.TimelineEventnow has aloopcallback which will be called before its next iteration. Fix #6560 (thanks @micsun-al) - The
Curves.PathmethodslineToandmoveTonow supportTypes.Math.Vector2Likeas the first parameter. Fix #6557 (thanks @wayfu) - The
BitmapText.setFontmethod 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) WebAudioSoundwill now sethasEnded = falseas part ofstopAndRemoveBufferSource, after the source has been stopped and disconnected. This should prevent it from being left in atruestate if the sourceonendedcallback fired late, after the sound had been re-played. Fix #6657 (thanks @Demeno)- The
ScaleManager.orientationChangeevent 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.updateTileDatamethod has two new optional parametersoffsetXandoffsetYwhich allow you to set the offset that the tile data starts from within the base source texture.
Bug Fixes
Factory.staticBodyhad the wrong return type in the docs/TS defs. Fix #6693 (thanks @ddhaiby)- The
Time.Timelineclass didn't show as extending the Event Emitter, or haveconfigas an optional argument in the docs / TS defs. Fix #6673 (thanks @ghclark2) - The
Animations.AnimationFramememberdurationis now the complete duration of the frame, which is a breaking change. Before thisAnimations.AnimationState#msPerFramewas combined withAnimations.AnimationFrame#durationwhich wasn't intuitive. The fix to removeAnimations.AnimationState#msPerFramefromAnimations.AnimationFrame#durationhas been removed from theAnimations.AnimationManagermethodcreateFromAsepritebecause of this clarification. Fix #6712 (thanks @Nerodon @TomMalitz) - The
NineSliceGame Object methodsetSizenow recalculates its origin by calling theupdateDisplayOriginmethod. Fix #6713 (thanks @dhashvir) - The
NineSliceGame Object method no longer defaults origin to0.5. Fix #6655 (thanks @michalfialadev) - When a
LayerGame 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) DynamicTexturewill now automatically callsetSize(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.setSizewill now check to see if theglTexturebound 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.Bodyfunctionscalehas been updated so if the Body originally had aninertiaofInfinitythis 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.weightedPickmethod to avoid sampling past the last element. Fix #6701 (thanks @jameskirkwood) - The
Physics.Matter.FactorymethodpointerConstraintno longer returns an error when it can't find the camera. Fix #6684 (thanks @spritus) - The
Physics.Arcade.StaticBodymethodresetnow re-appliesoffsetvalues. Fix #6729 (thanks @samme) - The
VideoGame Object now has a starting texture, which stops errors with accessingframebefore the video loads the first frame. Fix #6475 (thanks @rexrainbow @JoeSiu) - The
Device.Browser.safariregular expression has been strenghtened so it now captures versions with double or triple periods in. Previously it would fail forVersion/17.2.1due to the minor value. (thanks watcher) - The
BrowserDevice class will no longer think that Chrome is Mobile Safari on iOS devices. Fix #6739 (thanks @michalfialadev) - The
GameObjectCreatormethodcontainernow includes all children in the config, accessed viaScene.make.container. Fix #6743 (thanks @Fake) - Tilemaps that have been created using Tiles taken from a Sprite Sheet embedded in a Texture Atlas (via
addSpriteSheetFromAtlasandTilemap.addTilesetImage) will now render correctly. Fix #6691 (thanks @Antriel) - The
TilemapWebGLRendererfunction 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.collideSpriteVsTilemapLayermethod 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.base64is a new read-only boolean property that is set if the file contains a Data URI encoded string.Loader.File.onBase64Loadis a new method that is called when the file has finished decoding from a Data URI.- The
ImageFilewill now default to using the Image Load Element if a base64 file is detected, instead of throwing a console warning about unsupported types. - The
XHRLoaderwill 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
preUpdateautomatically when theplaymethod 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.setSlotAlphais a new method that allows you to set the alpha on a specific slot in a Spine skeleton.- The
SpineGameObject.setAlphamethod 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 newsetSlotAlphamethod instead. Fix #6571 (thanks @spayton) - The
SpineFile.onFileCompletehandler was running a regular expression againstfile.srcinstead offile.url, sometimes leading to double paths in the atlas paths on loading. Fix #6642 (thanks @rez23)
Updates
- The
TweenChainBuilderwas incorrectly setting thepersistflag on the Chain totrue, which goes against what the documentation says. It now correctly sets it tofalse. 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
droppedargument has now been adeded to the documentation for theDRAG_ENDandGAMEOBJECT_DRAG_ENDevents. (thanks @samme) Container.onChildDestroyedis 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
TextandTileSpriteGame Objects now place their textures into the globalTextureManagerand a_textureKeyprivate string property has been added which contains a UUID to reference that texture. - The
Tilemaps.Components.WeightedRandomizemethod now uses the PhaserMath.RND.fracmethod with a seed instead of theMath.Randomstatic method. (thanks @jorbascrumps) Tilemaps.Components.IsometricCullTilesdoes theCheckIsoBoundsmethod check last when building the outputArray, as to help optimize in situations where the tile would not be visible anyways. (thanks @zegenie)Tilemaps.Components.WeightedRandomizenow uses the PhaserMath.RND.fracmethod with a seed instead theMath.Randomstatic method. (thanks @jorbascrumps)- The
LayerGame Object has had itsremoveAll,removeandaddmethods removed. These methods are all still available via theListclass that Layer inherits, but thedestroyChildparameters are no longer available. - The
Renderer.CanvasandRenderer.WebGLwill now only be included in the build file if the corresponding feature flagsCANVAS_RENDERERand/orWEBGL_RENDERERare set totrue. For Canvas only builds this saves a lot of space in the build. (thanks @samme) - You can now specify an
autoResizeboolean in theRenderTargetConfigwhich is passed to the Render Targets when they are created by a pipeline. - The
UtilityPipelinenow setsautoResizetotruein its Render Target Config, so that the globalfullFrameandhalfFrameRender Targets will automatically resize if the renderer changes. Actions.PlaceOnLinenow has an addedeaseparameter 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
XHRLoaderwill now listen forontimeoutand if triggered it will hand over to theFile.onErrorhandler. This prevents the Loader from stalling if a file times out. Fix #6472 (thanks @343dev) LightPipeline.currentNormalMapwas incorrectly documented as being a property ofWebGLRenderer.Meshbased Game Objects now can use an input config with thesetInteractivemethod, which supports the optionsdraggable,dropzone,cursoranduserHandCursor. Fix #6510 #6652 (thanks @Baegus @Neppord)
Bug Fixes
- The
InputManager.onTouchMovefunction 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.staticBodyhad the wrong return type in the docs/TS defs. Fix #6693 (thanks @ddhaiby)- The
Time.Timelineclass didn't show as extending the Event Emitter, or haveconfigas an optional argument in the docs / TS defs. Fix #6673 (thanks @ghclark2) - The
Animations.AnimationFramememberdurationis now the complete duration of the frame, which is a breaking change. Before thisAnimations.AnimationState#msPerFramewas combined withAnimations.AnimationFrame#durationwhich wasn't intuitive. The fix to removeAnimations.AnimationState#msPerFramefromAnimations.AnimationFrame#durationhas been removed from theAnimations.AnimationManagermethodcreateFromAsepritebecause of this clarification. Fix #6712 (thanks @Nerodon @TomMalitz) - The
NineSliceGame Object methodsetSizenow recalculates its origin by calling theupdateDisplayOriginmethod. (thanks @dhashvir) - When a
LayerGame 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) DynamicTexturewill now automatically callsetSize(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.setSizewill now check to see if theglTexturebound 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
BloomFXandBlurFXand any custom pipeline that relies on using theUtilityPipelinefull or half frame targets will now correctly draw even after the renderer size changes. Fix #6677 (thanks @Nerodon) - The
PostFXPipeline.postBatchmethod will now skiponDrawif 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.Bodyfunctionscalehas been updated so if the Body originally had aninertiaofInfinitythis 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.weightedPickmethod to avoid sampling past the last element. Fix #6701 (thanks @jameskirkwood) - The touch event handler
onTouchEndWindownow stops pointer events when clicking through DOM elements to input. Fix #6697 (thanks @laineus) - The
Physics.Matter.FactorymethodpointerConstraintno longer returns an error when it can't find the camera. Fix #6684 (thanks @spritus) - The
Physics.Arcade.StaticBodymethodresetnow re-appliesoffsetvalues. Fix #6729 (thanks @samme) - The
Input.InputPluginmethoddisablewhich is called byGameObjects.GameObject#disableInteractivekeeps its temp hit box value which stops propagation to interactive Game Objects in another scene. Fix #6601 (thanks @UnaiNeuronUp) - Using
setInteractiveandremoveInteractivemethods of a Game Object outside of the game loop would cause an error in whichInput.InputManager#resetCursorwould 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.base64is a new read-only boolean property that is set if the file contains a Data URI encoded string.Loader.File.onBase64Loadis a new method that is called when the file has finished decoding from a Data URI.- The
ImageFilewill now default to using the Image Load Element if a base64 file is detected, instead of throwing a console warning about unsupported types. - The
XHRLoaderwill 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
preUpdateautomatically when theplaymethod 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.setSlotAlphais a new method that allows you to set the alpha on a specific slot in a Spine skeleton.- The
SpineGameObject.setAlphamethod 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 newsetSlotAlphamethod instead. Fix #6571 (thanks @spayton) - The
SpineFile.onFileCompletehandler was running a regular expression againstfile.srcinstead offile.url, sometimes leading to double paths in the atlas paths on loading. Fix #6642 (thanks @rez23)
Updates
- The
TweenChainBuilderwas incorrectly setting thepersistflag on the Chain totrue, which goes against what the documentation says. It now correctly sets it tofalse. 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
droppedargument has now been adeded to the documentation for theDRAG_ENDandGAMEOBJECT_DRAG_ENDevents. (thanks @samme) Container.onChildDestroyedis 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
TextandTileSpriteGame Objects now place their textures into the globalTextureManagerand a_textureKeyprivate string property has been added which contains a UUID to reference that texture. - The
Tilemaps.Components.WeightedRandomizemethod now uses the PhaserMath.RND.fracmethod with a seed instead of theMath.Randomstatic method. (thanks @jorbascrumps) Tilemaps.Components.IsometricCullTilesdoes theCheckIsoBoundsmethod check last when building the outputArray, as to help optimize in situations where the tile would not be visible anyways. (thanks @zegenie)Tilemaps.Components.WeightedRandomizenow uses the PhaserMath.RND.fracmethod with a seed instead theMath.Randomstatic method. (thanks @jorbascrumps)- The
LayerGame Object has had itsremoveAll,removeandaddmethods removed. These methods are all still available via theListclass that Layer inherits, but thedestroyChildparameters are no longer available. - The
Renderer.CanvasandRenderer.WebGLwill now only be included in the build file if the corresponding feature flagsCANVAS_RENDERERand/orWEBGL_RENDERERare set totrue. For Canvas only builds this saves a lot of space in the build. (thanks @samme) - You can now specify an
autoResizeboolean in theRenderTargetConfigwhich is passed to the Render Targets when they are created by a pipeline. - The
UtilityPipelinenow setsautoResizetotruein its Render Target Config, so that the globalfullFrameandhalfFrameRender Targets will automatically resize if the renderer changes. Actions.PlaceOnLinenow has an addedeaseparameter 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
XHRLoaderwill now listen forontimeoutand if triggered it will hand over to theFile.onErrorhandler. This prevents the Loader from stalling if a file times out. Fix #6472 (thanks @343dev)
Bug Fixes
- The
InputManager.onTouchMovefunction 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.staticBodyhad the wrong return type in the docs/TS defs. Fix #6693 (thanks @ddhaiby)- The
Time.Timelineclass didn't show as extending the Event Emitter, or haveconfigas an optional argument in the docs / TS defs. Fix #6673 (thanks @ghclark2) - The
Animations.AnimationFramememberdurationis now the complete duration of the frame, which is a breaking change. Before thisAnimations.AnimationState#msPerFramewas combined withAnimations.AnimationFrame#durationwhich wasn't intuitive. The fix to removeAnimations.AnimationState#msPerFramefromAnimations.AnimationFrame#durationhas been removed from theAnimations.AnimationManagermethodcreateFromAsepritebecause of this clarification. Fix #6712 (thanks @Nerodon @TomMalitz) - The
NineSliceGame Object methodsetSizenow recalculates its origin by calling theupdateDisplayOriginmethod. (thanks @dhashvir) - When a
LayerGame 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) DynamicTexturewill now automatically callsetSize(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.setSizewill now check to see if theglTexturebound 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
BloomFXandBlurFXand any custom pipeline that relies on using theUtilityPipelinefull or half frame targets will now correctly draw even after the renderer size changes. Fix #6677 (thanks @Nerodon) - The
PostFXPipeline.postBatchmethod will now skiponDrawif 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.Bodyfunctionscalehas been updated so if the Body originally had aninertiaofInfinitythis 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.weightedPickmethod to avoid sampling past the last element. Fix #6701 (thanks @jameskirkwood) - The touch event handler
onTouchEndWindownow stops pointer events when clicking through DOM elements to input. Fix #6697 (thanks @laineus) - The
Physics.Matter.FactorymethodpointerConstraintno 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
roundPixelsproperty is nowtrueby 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 theroundPixelsproperty in the Game Config tofalse. Note that onlyroundPixelshas been set totrue. ThepixelArtproperty remainsfalse. 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
uRoundPixelswhich 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.batchSpritehas been updated to correctly use the CameraroundPixelsproperty and apply it to thedrawImagecall.Camera.preRenderwill no longer round the origin, follow coordinates or scrollX/Y coordinates. It will still round the World view.- The
MultiPipeline.batchSpritemethod (which is also used by the Single Pipeline and Mobile Pipeline) will no longer useroundPixelswhen 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.setQuadno longer uses an anonymous function forroundPixels, which will help with performance.- The
TransformMatrix.setQuadmethod signature has changed slightly. TheroundPixelsparameter is now optional and defaults tofalse. 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
NineSliceGame Object without specifying a width or height for it. If you do this, it will use the size of the texture frame instead. - The
NineSliceGame 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.setSlicesmethod has a new optional boolean parameterskipScale9which will allow you to set the border values of the Nine Slice directly, even if its Frame has associated scale9 data Frame.setScale9is 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.scale9is a new read-only boolean property that returnstrueif the Frame has scale9 data associated with it.Frame.is3Sliceis a new read-only boolean property that returnstrueif the Frame has scale9 data associated with it that is 3-slice instead of 9-slice.- The
JSONHashtexture parser will now check forscale9data in the JSON and if found, set it via theFrame.setScale9method. - The
JSONArraytexture parser will now check forscale9data in the JSON and if found, set it via theFrame.setScale9method.
New Features - Arcade Physics
- Arcade Physics Bodies have a new method called
setDirectControlwhich toggles a new boolean propertydirectControl. 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.setSlideFactoris a new method that sets the Body'sslideFactorproperty.- The Arcade Physics World has a new method
nextCategorywhich 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:
collisionCategoryandcollisionMask. 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. setCollisionCategoryis 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.setCollidesWithis 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.resetCollisionis 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.
disablePreFXset this totruein your game config to disable the creation and use of Pre FX on all Game Objects.disablePostFXset this totruein your game config to disable the creation and use of Post FX on all Game Objects.- The
PipelineManagerwill now delay the creation of the FX Pipelines until itsbootmethod, using these config values to determine if it should proceed. - The
PipelineManager.renderTargetsarray will no longer be pre-populated if you disable Pre FX, saving on texture memory. FX.Circle.backgroundAlphais a new property that allows you to set the amount of the alpha of the background color in the Circle FX (thanks @rexrainbow)PostFXPipeline.bootFXis a new method, which is the previousbootmethod 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
PostFXPipelinewill now setautoResizetotrueon all of itsRenderTargetinstances. This fixes an issue where thePostFXPipelinewould 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.Blurdidn't set thequalityparameter 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
BlurFXPipelinedidn'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
FXBlurLowfragment shader didn't have theoffsetuniform. 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
batchTexturethat 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.setRTLis 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.singleStepis a new method that will advance the Arcade Physics World simulation by exactly 1 step (thanks @monteiz)Tilemaps.ObjectLayer.idis 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.idis a new property that returns the ID of the Data Layer, if specified within Tiled, or zero otherwise (thanks @rui-han-crh)Text.setLetterSpacingis a new method andText.letterSpacingis 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.clearDeathZonesis a new method that will clear all previously created Death Zones from a Particle Emitter (thanks @rexrainbow)ParticleEmitter.clearEmitZonesis a new method that will clear all previously created Emission Zones from a Particle Emitter (thanks @rexrainbow)- The
GameObject.setTexturemethod has 2 new optional parameters:updateSizeandupdateOrigin, which are both passed to thesetFramemethod 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 isfalseby 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 newAnimation.randomFrameandAnimationState.randomFrameproperties. - You can now use a
Phaser.Types.Animations.PlayAnimationConfigobject in theanimsproperty of theParticleEmitterconfiguration 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.setTintFillis 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 thesetTintmethod uses.Tile.tintFillis a new boolean property that controls if the tile tint is additive or fill based. This is used in the TilemapLayerWebGLRenderer function.RenderTarget.willResizeis a new method that will returntrueif the Render Target will be resized as a result of the new given width and height values.Structs.Map.setAllis 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
TimelineEventyou can now set a new optional callback:if. If set, this callback is invoked at the start of the TimelineEvent. If it returnstrue, 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.setFromObjectsis 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
WebAudioSoundManagerwill now bind thebodyto theremoveEventListenermethod, if it exists, to prevent memory leaks (thanks @wjaykim) - The
AnimationManager.globalTimeScaleproperty 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
RopeGame Object now callsinitPostPipelineallowing you to use Post FX directly on it, such as glow, blur, etc. Fix #6550 (thanks @rexrainbow) - The
Tween.stopmethod will now check to see ifTween.parentis set. If not, it won't try to set a pending removal state or dispatch an event, which should help guard against errors whereTween.stopis called by mistake on already destroyed tweens (thanks @orcomarcio) - The
Tween.removemethod will now check to see ifTween.parentexists before trying to remove it from the parent. This should help guard against errors whereTween.removeis called by mistake on already removed or destroyed tweens. Fix #6539 (thanks @orcomarcio) Particle.alphais now clamped to the range 0 to 1 within theupdatemethod, preventing it from going out of range. Fix #6551 (thanks @orcomarcio)Math.Wraphas been reverted to the previous version. Fix #6479 (thanks @EmilSV)- The
GraphicsGame 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
mipmapFilterproperty in the Game Config is a valid mipmap before assigning it. - A small amount of unused code has been removed from the
Polygon.setTomethod (thanks @Trissolo) - The
WebGLRenderer.deleteFramebuffermethod 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
MeshGame Object interactive, it will now bind to the scope of the Mesh and uses the currentfacesin 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
AppleWebKitwill now set theDevice.es2019flag totrue. 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.dirtyGame 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
HTMLVideoElementbefore trying to inspect its prototype. This should help in non-browser environments. Plane.originXandoriginYare two new read-only properties that return the origin of the Plane, which is always 0.5 (thanks @rexrainbow)- The
LoaderPluginwill now callremoveAllListeners()as part of itsshutdownmethod, which will clear any event listeners bound to a Loader instance of the Scene, during the Scene shutdown. Fix #6633 (thanks @samme) SetCollisionObjectis a new function that Arcade Physics bodies use internally to create and reset theirArcadeBodyCollisiondata objects.DynamicTexture.setFromRenderTargetis 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
renderTextureproperty toundefinedto ensure the reference is cleared. TransformMatrix.setToContextwill now usesetTransform(this)as 'this' is an equivalent object that this method can natively take.- Optimized
WebGLRenderer.setTextureFilterso it no longer uses a temporary array for the filter mode. - The
MultiPipeline.batchTexturemethod has a new optional boolean parameterskipPrePostthat will force the call to ignore calling thepreBatchandpostBatchPipeline 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
tintproperty can now act as a getter and a setter, where-as previously it was only a setter. Reading this property returns the equivalent of thetintTopLeftvalue (thanks @rexrainbow) ParticleEmitter.addDeathZonenow returns an array of the Death Zone instances created, rather than just a single zone. This makes it functionally the same asaddEmitZone(thanks @AlvaroEstradaDev)- The
GameObjects.Layer.addmethod is now chainable (thanks @rexrainbow) - The
GameObjects.Layer.removeandremoveAllmethods are now chainable and have a new optional boolean parameterdestroyChild, 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.defaultDivisionsis a new property that holds the default number of divisions to split the Path in to (thanks @AlvaroEstradaDev)- The
Curves.Path.getPointsmethod has a new optional parameterstepRatewhich allows you to set the distance between points on the curve, and defaults todefaultDivisions(thanks @AlvaroEstradaDev) - The
Timelineclass will now emit the newPhaser.Time.Events#COMPLETEevent when it completes. It will also no longer process itsupdatemethod once the Timeline has completed (thanks @rexrainbow) - The
BaseSound.destroymethod will now callBaseSound.stopwhich will reset theisPlayingand other flags. Fix #6645 (thanks @rexrainbow) - The
RandomDataGenerator#weightedPickmethod 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.runDestroyit will now check forthis.domContainer.parentNodebefore 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_READYevent, 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 thestampImage. This fixes an issue where the stamp would throw a run-time error if the game didn't feature apreloadfunction. Fix #6616 (thanks @rexrainbow)
Bug Fixes
Particle.scaleYwould always be set to thescaleXvalue, even if given a different one within the config. It will now use its own value correctly.Array.Matrix.RotateLeftwas missing thetotalparameter, which controls how many times to rotate the matrix.Array.Matrix.RotateRightwas missing thetotalparameter, which controls how many times to rotate the matrix.Array.Matrix.TranslateMatrixdidn't work with any translation values above 1 due to missing parameters inRotateLeftandRotateRight- The
Tilemap.createFromObjectsmethod wouldn't always copy custom properties to the target objects or Data Manager. Fix #6391 (thanks @samme @paxperscientiam) - The
scale.minandscale.maxwidthandheightproperties in Game Config were ignored by the Game constructor, which was expectingminWidthandminHeight. This now matches the documentation. Fix #6501 (thanks @NikitaShpanko @wpederzoli) - Due to a copy-paste bug, the
Actions.GetLastfunction had the same code as theGetFirstfunction. It now does what you'd expect it to do. Fix #6513 (thanks @dmokel) - The
TilemapLayer.PutTileAtmethod would use an incorrect local GID if the Tilemap Layer wasn't using all available tilesets. Fix #5931 (thanks @christianvoigt @wjaykim) - The
TextureManager.addSpriteSheetmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @charlieschwabacher) - The
HexagonalCullBoundsfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
HexagonalGetTileCornersfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
HexagonalTileToWorldXYfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
BitmapTextGame 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 theinterpolationproperty as well. It now defaults tolinearif not given. Fix #6551 (thanks @orcomarcio) - The Matter Physics
ignoreGravityboolean is now checked during the Matter Engine internal functions, allowing this property to now work again. Fix #6473 (thanks @peer2p) Group.createFromConfigwill now check to see if the config contains eitherinternalCreateCallbackorinternalRemoveCallbackand 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)PhysicsGroupwill now set theclassTypeand null theconfigwhen an array of single configuration objects is given in the constructor. Fix #6519 (thanks @samme)- The
PathFollower.pathUpdatemethod will now check if thetweenproperty has a validdatacomponent before running the update. This prevents a call toPathFollower.stopFollowfrom throwing aCannot 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) Tilewas incorrectly using theAlphaGame Object component, instead of theAlphaSinglecomponent, 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.addAtlasJSONArraymethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addAtlasJSONHashmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addAtlasXMLmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addUnityAtlasmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) DynamicTexture.preDestroywas never called, leading to an accumulation of framebuffers in memory. This method has now been renamed todestroyand cleans all references correctly.- If you gave the
widthorheightin 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
ParticleEmitterWebGLRendererhas been refactored so that theparticle.frameis used as the source of theglTextureused 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.setSizewill now check to see if the body has a Game Object or not, and only callgetCenterand the frame sizes if it has. This fixes a bug where callingphysics.add.staticBodywould throw an error if you provided a width and height. Fix #6630 (thanks @Legend-Master)- The
DynamicTexture.fillmethod will now correctly draw the fill rectangle if thewidthandheightare 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.setLineWidthmethod 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
DynamicTexturewas leaking memory by leaving a WebGLTexture in memory when itssetSizemethod 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.widthandheightwere missing from the class definition, even though they were set and used internally. They're now exposed as read-only properties.- The
BitmapMaskwouldn'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.GetLineToPointsfunction 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
MultiAtlasFile Loader didn't prepend theLoader.prefixif 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.setFiltermethod will now check to see ifrendereris defined before accessing itsglproperty. 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.setSkeletonFromJSONhas been fixed so it now passes the parameters in the correct order to thesetSkeletonmethod. 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
setDirectControlwhich toggles a new boolean propertydirectControl. 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.setSlideFactoris a new method that sets the Body'sslideFactorproperty.- The Arcade Physics World has a new method
nextCategorywhich 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:
collisionCategoryandcollisionMask. 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. setCollisionCategoryis 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.setCollidesWithis 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.resetCollisionis 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.setRTLis 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.backgroundAlphais 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.singleStepis a new method that will advance the Arcade Physics World simulation by exactly 1 step (thanks @monteiz)Tilemaps.ObjectLayer.idis 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.idis a new property that returns the ID of the Data Layer, if specified within Tiled, or zero otherwise (thanks @rui-han-crh)Text.setLetterSpacingis a new method andText.lineSpacingis 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.clearDeathZonesis a new method that will clear all previously created Death Zones from a Particle Emitter (thanks @rexrainbow)ParticleEmitter.clearEmitZonesis a new method that will clear all previously created Emission Zones from a Particle Emitter (thanks @rexrainbow)- The
GameObject.setTexturemethod has 2 new optional parameters:updateSizeandupdateOrigin, which are both passed to thesetFramemethod 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 isfalseby 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 newAnimation.randomFrameandAnimationState.randomFrameproperties. - You can now use a
Phaser.Types.Animations.PlayAnimationConfigobject in theanimsproperty of theParticleEmitterconfiguration 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.setTintFillis 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 thesetTintmethod uses.Tile.tintFillis a new boolean property that controls if the tile tint is additive or fill based. This is used in the TilemapLayerWebGLRenderer function.
Updates
- The
WebAudioSoundManagerwill now bind thebodyto theremoveEventListenermethod, if it exists, to prevent memory leaks (thanks @wjaykim) - The
AnimationManager.globalTimeScaleproperty 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
RopeGame Object now callsinitPostPipelineallowing you to use Post FX directly on it, such as glow, blur, etc. Fix #6550 (thanks @rexrainbow) - The
Tween.stopmethod will now check to see ifTween.parentis set. If not, it won't try to set a pending removal state or dispatch an event, which should help guard against errors whereTween.stopis called by mistake on already destroyed tweens (thanks @orcomarcio) - The
Tween.removemethod will now check to see ifTween.parentexists before trying to remove it from the parent. This should help guard against errors whereTween.removeis called by mistake on already removed or destroyed tweens. Fix #6539 (thanks @orcomarcio) Particle.alphais now clamped to the range 0 to 1 within theupdatemethod, preventing it from going out of range. Fix #6551 (thanks @orcomarcio)Math.Wraphas been reverted to the previous version. Fix #6479 (thanks @EmilSV)- The
GraphicsGame 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
mipmapFilterproperty in the Game Config is a valid mipmap before assigning it. - A small amount of unused code has been removed from the
Polygon.setTomethod (thanks @Trissolo) - The
WebGLRenderer.deleteFramebuffermethod 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
MeshGame Object interactive, it will now bind to the scope of the Mesh and uses the currentfacesin 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
AppleWebKitwill now set theDevice.es2019flag totrue. 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.dirtyGame 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
HTMLVideoElementbefore trying to inspect its prototype. This should help in non-browser environments. Plane.originXandoriginYare two new read-only properties that return the origin of the Plane, which is always 0.5 (thanks @rexrainbow)- The
LoaderPluginwill now callremoveAllListeners()as part of itsshutdownmethod, which will clear any event listeners bound to a Loader instance of the Scene, during the Scene shutdown. Fix #6633 (thanks @samme) SetCollisionObjectis a new function that Arcade Physics bodies use internally to create and reset theirArcadeBodyCollisiondata objects.DynamicTexture.setFromRenderTargetis 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
renderTextureproperty toundefinedto ensure the reference is cleared.
Bug Fixes
- The
PostFXPipelinewill now setautoResizetotrueon all of itsRenderTargetinstances. This fixes an issue where thePostFXPipelinewould 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.scaleYwould always be set to thescaleXvalue, even if given a different one within the config. It will now use its own value correctly.Array.Matrix.RotateLeftwas missing thetotalparameter, which controls how many times to rotate the matrix.Array.Matrix.RotateRightwas missing thetotalparameter, which controls how many times to rotate the matrix.Array.Matrix.TranslateMatrixdidn't work with any translation values above 1 due to missing parameters inRotateLeftandRotateRightFX.Blurdidn't set thequalityparameter 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
BlurFXPipelinedidn'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
FXBlurLowfragment shader didn't have theoffsetuniform. This is now passed in and applied to the resulting blur, preventing it from creating 45 degree artifacts (thanks Wayfinder) - The
Tilemap.createFromObjectsmethod wouldn't always copy custom properties to the target objects or Data Manager. Fix #6391 (thanks @samme @paxperscientiam) - The
scale.minandscale.maxwidthandheightproperties in Game Config were ignored by the Game constructor, which was expectingminWidthandminHeight. This now matches the documentation. Fix #6501 (thanks @NikitaShpanko @wpederzoli) - Due to a copy-paste bug, the
Actions.GetLastfunction had the same code as theGetFirstfunction. It now does what you'd expect it to do. Fix #6513 (thanks @dmokel) - The
TilemapLayer.PutTileAtmethod would use an incorrect local GID if the Tilemap Layer wasn't using all available tilesets. Fix #5931 (thanks @christianvoigt @wjaykim) - The
TextureManager.addSpriteSheetmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @charlieschwabacher) - The
HexagonalCullBoundsfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
HexagonalGetTileCornersfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
HexagonalTileToWorldXYfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
BitmapTextGame 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 theinterpolationproperty as well. It now defaults tolinearif not given. Fix #6551 (thanks @orcomarcio) - The Matter Physics
ignoreGravityboolean is now checked during the Matter Engine internal functions, allowing this property to now work again. Fix #6473 (thanks @peer2p) Group.createFromConfigwill now check to see if the config contains eitherinternalCreateCallbackorinternalRemoveCallbackand 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)PhysicsGroupwill now set theclassTypeand null theconfigwhen an array of single configuration objects is given in the constructor. Fix #6519 (thanks @samme)- The
PathFollower.pathUpdatemethod will now check if thetweenproperty has a validdatacomponent before running the update. This prevents a call toPathFollower.stopFollowfrom throwing aCannot 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) Tilewas incorrectly using theAlphaGame Object component, instead of theAlphaSinglecomponent, 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.addAtlasJSONArraymethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addAtlasJSONHashmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addAtlasXMLmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addUnityAtlasmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) DynamicTexture.preDestroywas never called, leading to an accumulation of framebuffers in memory. This method has now been renamed todestroyand cleans all references correctly.- If you gave the
widthorheightin 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
ParticleEmitterWebGLRendererhas been refactored so that theparticle.frameis used as the source of theglTextureused 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.setSizewill now check to see if the body has a Game Object or not, and only callgetCenterand the frame sizes if it has. This fixes a bug where callingphysics.add.staticBodywould throw an error if you provided a width and height. Fix #6630 (thanks @Legend-Master)- The
DynamicTexture.fillmethod will now correctly draw the fill rectangle if thewidthandheightare 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.setLineWidthmethod 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
DynamicTexturewas leaking memory by leaving a WebGLTexture in memory when itssetSizemethod 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.widthandheightwere missing from the class definition, even though they were set and used internally. They're now exposed as read-only properties.- The
BitmapMaskwouldn'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.setSlideFactoris a new method that sets the Body'sslideFactorproperty.- The Arcade Physics World has a new method
nextCategorywhich 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:
collisionCategoryandcollisionMask. 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. setCollisionCategoryis 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.setCollidesWithis 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.resetCollisionis 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.setRTLis 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.backgroundAlphais 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.singleStepis a new method that will advance the Arcade Physics World simulation by exactly 1 step (thanks @monteiz)Tilemaps.ObjectLayer.idis 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.idis a new property that returns the ID of the Data Layer, if specified within Tiled, or zero otherwise (thanks @rui-han-crh)Text.setLetterSpacingis a new method andText.lineSpacingis 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.clearDeathZonesis a new method that will clear all previously created Death Zones from a Particle Emitter (thanks @rexrainbow)ParticleEmitter.clearEmitZonesis a new method that will clear all previously created Emission Zones from a Particle Emitter (thanks @rexrainbow)- The
GameObject.setTexturemethod has 2 new optional parameters:updateSizeandupdateOrigin, which are both passed to thesetFramemethod 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 isfalseby 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 newAnimation.randomFrameandAnimationState.randomFrameproperties. - You can now use a
Phaser.Types.Animations.PlayAnimationConfigobject in theanimsproperty of theParticleEmitterconfiguration 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.setTintFillis 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 thesetTintmethod uses.Tile.tintFillis a new boolean property that controls if the tile tint is additive or fill based. This is used in the TilemapLayerWebGLRenderer function.
Updates
- The
WebAudioSoundManagerwill now bind thebodyto theremoveEventListenermethod, if it exists, to prevent memory leaks (thanks @wjaykim) - The
AnimationManager.globalTimeScaleproperty 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
RopeGame Object now callsinitPostPipelineallowing you to use Post FX directly on it, such as glow, blur, etc. Fix #6550 (thanks @rexrainbow) - The
Tween.stopmethod will now check to see ifTween.parentis set. If not, it won't try to set a pending removal state or dispatch an event, which should help guard against errors whereTween.stopis called by mistake on already destroyed tweens (thanks @orcomarcio) - The
Tween.removemethod will now check to see ifTween.parentexists before trying to remove it from the parent. This should help guard against errors whereTween.removeis called by mistake on already removed or destroyed tweens. Fix #6539 (thanks @orcomarcio) Particle.alphais now clamped to the range 0 to 1 within theupdatemethod, preventing it from going out of range. Fix #6551 (thanks @orcomarcio)Math.Wraphas been reverted to the previous version. Fix #6479 (thanks @EmilSV)- The
GraphicsGame 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
mipmapFilterproperty in the Game Config is a valid mipmap before assigning it. - A small amount of unused code has been removed from the
Polygon.setTomethod (thanks @Trissolo) - The
WebGLRenderer.deleteFramebuffermethod 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
MeshGame Object interactive, it will now bind to the scope of the Mesh and uses the currentfacesin 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
AppleWebKitwill now set theDevice.es2019flag totrue. 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.dirtyGame 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
HTMLVideoElementbefore trying to inspect its prototype. This should help in non-browser environments. Plane.originXandoriginYare two new read-only properties that return the origin of the Plane, which is always 0.5 (thanks @rexrainbow)- The
LoaderPluginwill now callremoveAllListeners()as part of itsshutdownmethod, which will clear any event listeners bound to a Loader instance of the Scene, during the Scene shutdown. Fix #6633 (thanks @samme) SetCollisionObjectis a new function that Arcade Physics bodies use internally to create and reset theirArcadeBodyCollisiondata objects.DynamicTexture.setFromRenderTargetis 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
renderTextureproperty toundefinedto ensure the reference is cleared.
Bug Fixes
- The
PostFXPipelinewill now setautoResizetotrueon all of itsRenderTargetinstances. This fixes an issue where thePostFXPipelinewould 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.scaleYwould always be set to thescaleXvalue, even if given a different one within the config. It will now use its own value correctly.Array.Matrix.RotateLeftwas missing thetotalparameter, which controls how many times to rotate the matrix.Array.Matrix.RotateRightwas missing thetotalparameter, which controls how many times to rotate the matrix.Array.Matrix.TranslateMatrixdidn't work with any translation values above 1 due to missing parameters inRotateLeftandRotateRightFX.Blurdidn't set thequalityparameter 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
BlurFXPipelinedidn'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
FXBlurLowfragment shader didn't have theoffsetuniform. This is now passed in and applied to the resulting blur, preventing it from creating 45 degree artifacts (thanks Wayfinder) - The
Tilemap.createFromObjectsmethod wouldn't always copy custom properties to the target objects or Data Manager. Fix #6391 (thanks @samme @paxperscientiam) - The
scale.minandscale.maxwidthandheightproperties in Game Config were ignored by the Game constructor, which was expectingminWidthandminHeight. This now matches the documentation. Fix #6501 (thanks @NikitaShpanko @wpederzoli) - Due to a copy-paste bug, the
Actions.GetLastfunction had the same code as theGetFirstfunction. It now does what you'd expect it to do. Fix #6513 (thanks @dmokel) - The
TilemapLayer.PutTileAtmethod would use an incorrect local GID if the Tilemap Layer wasn't using all available tilesets. Fix #5931 (thanks @christianvoigt @wjaykim) - The
TextureManager.addSpriteSheetmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @charlieschwabacher) - The
HexagonalCullBoundsfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
HexagonalGetTileCornersfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
HexagonalTileToWorldXYfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
BitmapTextGame 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 theinterpolationproperty as well. It now defaults tolinearif not given. Fix #6551 (thanks @orcomarcio) - The Matter Physics
ignoreGravityboolean is now checked during the Matter Engine internal functions, allowing this property to now work again. Fix #6473 (thanks @peer2p) Group.createFromConfigwill now check to see if the config contains eitherinternalCreateCallbackorinternalRemoveCallbackand 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)PhysicsGroupwill now set theclassTypeand null theconfigwhen an array of single configuration objects is given in the constructor. Fix #6519 (thanks @samme)- The
PathFollower.pathUpdatemethod will now check if thetweenproperty has a validdatacomponent before running the update. This prevents a call toPathFollower.stopFollowfrom throwing aCannot 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) Tilewas incorrectly using theAlphaGame Object component, instead of theAlphaSinglecomponent, 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.addAtlasJSONArraymethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addAtlasJSONHashmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addAtlasXMLmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addUnityAtlasmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) DynamicTexture.preDestroywas never called, leading to an accumulation of framebuffers in memory. This method has now been renamed todestroyand cleans all references correctly.- If you gave the
widthorheightin 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
ParticleEmitterWebGLRendererhas been refactored so that theparticle.frameis used as the source of theglTextureused 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.setSizewill now check to see if the body has a Game Object or not, and only callgetCenterand the frame sizes if it has. This fixes a bug where callingphysics.add.staticBodywould throw an error if you provided a width and height. Fix #6630 (thanks @Legend-Master)- The
DynamicTexture.fillmethod will now correctly draw the fill rectangle if thewidthandheightare 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.setLineWidthmethod 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
DynamicTexturewas leaking memory by leaving a WebGLTexture in memory when itssetSizemethod 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.widthandheightwere missing from the class definition, even though they were set and used internally. They're now exposed as read-only properties.- The
BitmapMaskwouldn'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.setRTLis 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.backgroundAlphais 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.singleStepis a new method that will advance the Arcade Physics World simulation by exactly 1 step (thanks @monteiz)Tilemaps.ObjectLayer.idis 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.idis a new property that returns the ID of the Data Layer, if specified within Tiled, or zero otherwise (thanks @rui-han-crh)Text.setLetterSpacingis a new method andText.lineSpacingis 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.clearDeathZonesis a new method that will clear all previously created Death Zones from a Particle Emitter (thanks @rexrainbow)ParticleEmitter.clearEmitZonesis a new method that will clear all previously created Emission Zones from a Particle Emitter (thanks @rexrainbow)- The
GameObject.setTexturemethod has 2 new optional parameters:updateSizeandupdateOrigin, which are both passed to thesetFramemethod 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 isfalseby 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 newAnimation.randomFrameandAnimationState.randomFrameproperties. - You can now use a
Phaser.Types.Animations.PlayAnimationConfigobject in theanimsproperty of theParticleEmitterconfiguration 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
WebAudioSoundManagerwill now bind thebodyto theremoveEventListenermethod, if it exists, to prevent memory leaks (thanks @wjaykim) - The
AnimationManager.globalTimeScaleproperty 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
RopeGame Object now callsinitPostPipelineallowing you to use Post FX directly on it, such as glow, blur, etc. Fix #6550 (thanks @rexrainbow) - The
Tween.stopmethod will now check to see ifTween.parentis set. If not, it won't try to set a pending removal state or dispatch an event, which should help guard against errors whereTween.stopis called by mistake on already destroyed tweens (thanks @orcomarcio) - The
Tween.removemethod will now check to see ifTween.parentexists before trying to remove it from the parent. This should help guard against errors whereTween.removeis called by mistake on already removed or destroyed tweens. Fix #6539 (thanks @orcomarcio) Particle.alphais now clamped to the range 0 to 1 within theupdatemethod, preventing it from going out of range. Fix #6551 (thanks @orcomarcio)Math.Wraphas been reverted to the previous version. Fix #6479 (thanks @EmilSV)- The
GraphicsGame 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
mipmapFilterproperty in the Game Config is a valid mipmap before assigning it. - A small amount of unused code has been removed from the
Polygon.setTomethod (thanks @Trissolo) - The
WebGLRenderer.deleteFramebuffermethod 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
MeshGame Object interactive, it will now bind to the scope of the Mesh and uses the currentfacesin 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
AppleWebKitwill now set theDevice.es2019flag totrue. 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
PostFXPipelinewill now setautoResizetotrueon all of itsRenderTargetinstances. This fixes an issue where thePostFXPipelinewould 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.scaleYwould always be set to thescaleXvalue, even if given a different one within the config. It will now use its own value correctly.Array.Matrix.RotateLeftwas missing thetotalparameter, which controls how many times to rotate the matrix.Array.Matrix.RotateRightwas missing thetotalparameter, which controls how many times to rotate the matrix.Array.Matrix.TranslateMatrixdidn't work with any translation values above 1 due to missing parameters inRotateLeftandRotateRightFX.Blurdidn't set thequalityparameter 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
BlurFXPipelinedidn'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
FXBlurLowfragment shader didn't have theoffsetuniform. This is now passed in and applied to the resulting blur, preventing it from creating 45 degree artifacts (thanks Wayfinder) - The
Tilemap.createFromObjectsmethod wouldn't always copy custom properties to the target objects or Data Manager. Fix #6391 (thanks @samme @paxperscientiam) - The
scale.minandscale.maxwidthandheightproperties in Game Config were ignored by the Game constructor, which was expectingminWidthandminHeight. This now matches the documentation. Fix #6501 (thanks @NikitaShpanko @wpederzoli) - Due to a copy-paste bug, the
Actions.GetLastfunction had the same code as theGetFirstfunction. It now does what you'd expect it to do. Fix #6513 (thanks @dmokel) - The
TilemapLayer.PutTileAtmethod would use an incorrect local GID if the Tilemap Layer wasn't using all available tilesets. Fix #5931 (thanks @christianvoigt @wjaykim) - The
TextureManager.addSpriteSheetmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @charlieschwabacher) - The
HexagonalCullBoundsfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
HexagonalGetTileCornersfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
HexagonalTileToWorldXYfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
BitmapTextGame 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 theinterpolationproperty as well. It now defaults tolinearif not given. Fix #6551 (thanks @orcomarcio) - The Matter Physics
ignoreGravityboolean is now checked during the Matter Engine internal functions, allowing this property to now work again. Fix #6473 (thanks @peer2p) Group.createFromConfigwill now check to see if the config contains eitherinternalCreateCallbackorinternalRemoveCallbackand 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)PhysicsGroupwill now set theclassTypeand null theconfigwhen an array of single configuration objects is given in the constructor. Fix #6519 (thanks @samme)- The
PathFollower.pathUpdatemethod will now check if thetweenproperty has a validdatacomponent before running the update. This prevents a call toPathFollower.stopFollowfrom throwing aCannot 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) Tilewas incorrectly using theAlphaGame Object component, instead of theAlphaSinglecomponent, 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.addAtlasJSONArraymethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addAtlasJSONHashmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addAtlasXMLmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) - The
TextureManager.addUnityAtlasmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @1DAfT) DynamicTexture.preDestroywas never called, leading to an accumulation of framebuffers in memory. This method has now been renamed todestroyand cleans all references correctly.- If you gave the
widthorheightin 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
ParticleEmitterWebGLRendererhas been refactored so that theparticle.frameis used as the source of theglTextureused 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.setRTLis 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.backgroundAlphais 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.singleStepis a new method that will advance the Arcade Physics World simulation by exactly 1 step (thanks @monteiz)Tilemaps.ObjectLayer.idis 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.idis a new property that returns the ID of the Data Layer, if specified within Tiled, or zero otherwise (thanks @rui-han-crh)Text.setLetterSpacingis a new method andText.lineSpacingis 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.clearDeathZonesis a new method that will clear all previously created Death Zones from a Particle Emitter (thanks @rexrainbow)ParticleEmitter.clearEmitZonesis a new method that will clear all previously created Emission Zones from a Particle Emitter (thanks @rexrainbow)
Updates
- The
WebAudioSoundManagerwill now bind thebodyto theremoveEventListenermethod, if it exists, to prevent memory leaks (thanks @wjaykim) - The
AnimationManager.globalTimeScaleproperty 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
RopeGame Object now callsinitPostPipelineallowing you to use Post FX directly on it, such as glow, blur, etc. Fix #6550 (thanks @rexrainbow) - The
Tween.stopmethod will now check to see ifTween.parentis set. If not, it won't try to set a pending removal state or dispatch an event, which should help guard against errors whereTween.stopis called by mistake on already destroyed tweens (thanks @orcomarcio) - The
Tween.removemethod will now check to see ifTween.parentexists before trying to remove it from the parent. This should help guard against errors whereTween.removeis called by mistake on already removed or destroyed tweens. Fix #6539 (thanks @orcomarcio) Particle.alphais now clamped to the range 0 to 1 within theupdatemethod, preventing it from going out of range. Fix #6551 (thanks @orcomarcio)Math.Wraphas been reverted to the previous version. Fix #6479 (thanks @EmilSV)
Bug Fixes
Particle.scaleYwould always be set to thescaleXvalue, even if given a different one within the config. It will now use its own value correctly.Array.Matrix.RotateLeftwas missing thetotalparameter, which controls how many times to rotate the matrix.Array.Matrix.RotateRightwas missing thetotalparameter, which controls how many times to rotate the matrix.Array.Matrix.TranslateMatrixdidn't work with any translation values above 1 due to missing parameters inRotateLeftandRotateRightFX.Blurdidn't set thequalityparameter 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
BlurFXPipelinedidn'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
FXBlurLowfragment shader didn't have theoffsetuniform. This is now passed in and applued to the resulting blur, preventing it from creating 45 degree artifacts (thanks Wayfinder) - The
Tilemap.createFromObjectsmethod wouldn't always copy custom properties to the target objects or Data Manager. Fix #6391 (thanks @samme @paxperscientiam) - The
scale.minandscale.maxwidthandheightproperties in Game Config were ignored by the Game constructor, which was expectingminWidthandminHeight. This now matches the documnentation. Fix #6501 (thanks @NikitaShpanko @wpederzoli) - Due to a copy-paste bug, the
Actions.GetLastfunction had the same code as theGetFirstfunction. It now does what you'd expect it to do. Fix #6513 (thanks @dmokel) - The
TilemapLayer.PutTileAtmethod would use an incorrect local GID if the Tilemap Layer wasn't using all available tilesets. Fix #5931 (thanks @christianvoigt @wjaykim) - The
TextureManager.addSpriteSheetmethod would fail if aTextureinstance was given as the second parameter, throwing aCannot read property 'key' of null(thanks @charlieschwabacher) - The
HexagonalCullBoundsfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
HexagonalGetTileCornersfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
HexagonalTileToWorldXYfunction incorrectly referencedthiswithin it, instead oflayer(thanks @DaliborTrampota) - The
BitmapTextGame 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 theinterpolationproperty as well. It now defaults tolinearif not given. Fix #6551 (thanks @orcomarcio) - The Matter Physics
ignoreGravityboolean is now checked during the Matter Engine internal functions, allowing this property to now work again. Fix #6473 (thanks @peer2p) Group.createFromConfigwill now check to see if the config contains eitherinternalCreateCallbackorinternalRemoveCallbackand 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)PhysicsGroupwill now set theclassTypeand null theconfigwhen an array of single configuration objects is given in the constructor. Fix #6519 (thanks @samme)- The
PathFollower.pathUpdatemethod will now check if thetweenproperty has a validdatacomponent before running the update. This prevents a call toPathFollower.stopFollowfrom throwing aCannot 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:
- 14 bundled Special FX including Bloom, Blur, Distort, Glow, Wipe, and more
- Vastly improved Mobile Rendering Performance - over 7000% faster!
- New Timeline Sequencer for creating complex flows of events
- New Plane Game Object for perspective distortions
- New Nine Slice Game Object for perfect UI scaling
- Built-in Spector JS for WebGL debugging on desktop and mobile
- Brand new Video Game Object handles videos and media streams with ease
- Brand new Particle Emitter comes with explosive new features
- Support for Spatial Audio and distance-based volume
- New Spine 4 Plugin support
- Upgraded to Matter Physics v0.19
- New Tween Manager with better performance and memory management
- New Dynamic Textures for rendering to textures at runtime
- New TimeStep features and Timer Event Updates for enforcing fps rates and more
- Support for Compressed Textures
- ESM Module Support
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.
- Animation System
- Arcade Physics
- Bitmap and Geometry Masks
- Camera System
- Canvas Renderer
- WebGL Renderer
- Colors and Display
- Game, Device and Game Config
- Geometry, Paths and Curves
- Input System
- Loader System
- Scale Manager
- Scenes and Scene Manager
- Sound System
- Spine 3 Plugin
- Texture Manager
- Utils, Math and Actions
- Build Config and Browser Updates
Game Object Updates
Finally, here are the updates related to Game Objects:
- Bitmap Text Game Object
- Container Game Object
- Graphics Game Object
- Mesh Game Object, Vertices and Faces
- Text Game Object
- Tilemap Game Object
- All other Game Object related Updates
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,lsdand 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.preFXan instance of the FX Controller, which allows you to add and remove Pre FX from the Game Object. It features methods such asadd,removeandclear. Plus the following:GameObject.preFX.addGlowadds a Glow Pre FX effect to the Game Object.GameObject.preFX.addShadowadds a Shadow Pre FX effect to the Game Object.GameObject.preFX.addPixelateadds a Pixelate Pre FX effect to the Game Object.GameObject.preFX.addVignetteadds a Vignette Pre FX effect to the Game Object.GameObject.preFX.addShineadds a Shine Pre FX effect to the Game Object.GameObject.preFX.addBluradds a Blur Pre FX effect to the Game Object.GameObject.preFX.addGradientadds a Gradient Pre FX effect to the Game Object.GameObject.preFX.addBloomadds a Bloom Pre FX effect to the Game Object.GameObject.preFX.addColorMatrixadds a ColorMatrix Pre FX effect to the Game Object.GameObject.preFX.addCircleadds a Circle Pre FX effect to the Game Object.GameObject.preFX.addBarreladds a Barrel Pre FX effect to the Game Object.GameObject.preFX.addDisplacementadds a Displacement Pre FX effect to the Game Object.GameObject.preFX.addWipeadds a Wipe Pre FX effect to the Game Object.GameObject.preFX.addRevealadds a Reveal Pre FX effect to the Game Object.GameObject.preFX.addBokehadds a Bokeh Pre FX effect to the Game Object.GameObject.preFX.addTiltShiftadds a TiltShift Pre FX effect to the Game Object.
Available to all Game Objects:
GameObject.clearFXremoves both Pre and Post FX from the Game Object.GameObject.postFXan instance of the FX Controller, which allows you to add and remove Post FX from the Game Object. It features methods such asadd,removeandclear. Plus the following:GameObject.postFX.addGlowadds a Glow Post FX effect to the Game Object.GameObject.postFX.addShadowadds a Shadow Post FX effect to the Game Object.GameObject.postFX.addPixelateadds a Pixelate Post FX effect to the Game Object.GameObject.postFX.addVignetteadds a Vignette Post FX effect to the Game Object.GameObject.postFX.addShineadds a Shine Post FX effect to the Game Object.GameObject.postFX.addBluradds a Blur Post FX effect to the Game Object.GameObject.postFX.addGradientadds a Gradient Post FX effect to the Game Object.GameObject.postFX.addBloomadds a Bloom Post FX effect to the Game Object.GameObject.postFX.addColorMatrixadds a ColorMatrix Post FX effect to the Game Object.GameObject.postFX.addCircleadds a Circle Post FX effect to the Game Object.GameObject.postFX.addBarreladds a Barrel Post FX effect to the Game Object.GameObject.postFX.addDisplacementadds a Displacement Post FX effect to the Game Object.GameObject.postFX.addWipeadds a Wipe Post FX effect to the Game Object.GameObject.postFX.addRevealadds a Reveal Post FX effect to the Game Object.GameObject.postFX.addBokehadds a Bokeh Post FX effect to the Game Object.GameObject.postFX.addTiltShiftadds 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:
SpatialSoundConfigis a new configuration object that contains the properties required to create and set the values of a spatial sound:SpatialSoundConfig.xsets the horizontal position of the audio in a right-hand Cartesian coordinate system.SpatialSoundConfig.ysets the vertical position of the audio in a right-hand Cartesian coordinate system.SpatialSoundConfig.zsets the longitudinal (back and forth) position of the audio in a right-hand Cartesian coordinate system.SpatialSoundConfig.panningModelis an enumerated value determining which spatialization algorithm to use to position the audio in 3D space. Can be eitherequalpowerorHRTF. The default value isequalpower.SpatialSoundConfig.distanceModelsets 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.orientationXsets the horizontal position of the audio source's vector in a right-hand Cartesian coordinate system.SpatialSoundConfig.orientationYsets the vertical position of the audio source's vector in a right-hand Cartesian coordinate system.SpatialSoundConfig.orientationZsets the longitudinal (back and forth) position of the audio source's vector in a right-hand Cartesian coordinate system.SpatialSoundConfig.refDistanceis 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 onrolloffFactoranddistanceModel.SpatialSoundConfig.maxDistanceis the maximum distance between the audio source and the listener, after which the volume is not reduced any further.SpatialSoundConfig.rolloffFactoris 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.coneInnerAnglesets the angle, in degrees, of a cone inside of which there will be no volume reduction.SpatialSoundConfig.coneOuterAnglesets the angle, in degrees, of a cone outside of which the volume will be reduced by a constant value, defined by theconeOuterGainproperty.SpatialSoundConfig.coneOuterGainsets the amount of volume reduction outside the cone defined by theconeOuterAngleattribute. Its default value is 0, meaning that no sound can be heard. A value between 0 and 1.SpatialSoundConfig.followsets 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.setListenerPositionis a new method that allows you to set the position of the Spatial Audio listener.BaseSoundManager.listenerPositionis a new Vector2 that stores the position of the Spatial Audio listener.WebAudioSound.spatialNodeis a new property that holds thePanNodethat is used to position the sound in 3D space.WebAudioSound.spatialSourceis a new property that holds a Vector2 that stores the position of the sound in 3D space.WebAudioSound.xis 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.yis 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
drawDebugon 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
addandmakefunctions 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 (viaaddToScene: 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
SpineFileloader has now been updated so that the always-unique Spine key is pre-pended to the filename, for example if the key wasbonusand the PNG in the atlas wascoin.pngthen the final key (as stored in the Texture Manager) is nowbonus:coin.png. TheSpinePlugin.getAtlasCanvasandgetAtlasWebGLmethods have been updated to reflect this change. Fix #6022 (thanks @orjandh) - If a
SpineContainerhad 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isPreFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allPreFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Pre FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.- The
WebGLPipeline.setTimemethod has a new optional parametershader, which allows you to control the shader on which the time value is set. - If you add
#define SHADER_NAMEto the start of your shader then it will be picked up as theWebGLShadername during thesetShadersFromConfigprocess withinWebGLPipeline. - Calling
setPostPipelineon a Game Object will now pass thepipelineDataconfiguration object (if provided) to the pipeline instance being created. PipelineManager.getPostPipelinenow has an optional 3rd parameter, aconfigobject 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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
advanceproperty, or by calling the newParticleEmitter.fastForwardmethod. 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.startmethod has a new optional parameteradvancethat 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.durationis a new property that contains the duration that the Emitter will emit particles for in flow mode.- The
ParticleEmitter.startmethod has a new optional parameterduration, 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.stopmethod has a new optional parameterkill. 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
stopAfterproperty. This, combined with thefrequencyproperty 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
stopAftercounter is reset each time you call thestartorflowmethods.
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
holdconfiguration 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.STARTevent is fired whenever the Emitter begins emission of particles in flow mode. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.EXPLODEevent is fired whenever the Emitter explodes a bunch of particles via theexplodemethod. A reference to theParticleEmitterand a reference to the most recently firedParticleinstance are the two parameters. - The
Particles.Events.DEATH_ZONEevent is fired whenever a Particle is killed by a Death Zone. A reference to theParticleEmitter, the killedParticleand theDeathZonethat caused it are the 3 parameters. - The
Particles.Events.STOPevent is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call thestopmethod, or when an Emitter hits its duration or stopAfter limit. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.COMPLETEevent 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.addEmitZonemethod:
```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
totalproperty.EdgeZone.totalandRandomZone.totalare 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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeEmitZoneis a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getEmitZoneis a new method that Particles call when they are 'fired' in order to set their starting position, if any.- The property
ParticleEmitter.emitZonehas been removed. It has been replaced with the newParticleEmitter.emitZonesarray-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.addDeathZonemethod:
```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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeDeathZoneis a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getDeathZoneis 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.deathZonehas been removed. It has been replaced with the newParticleEmitter.deathZonesarray-based property.
Particle Colors
- You can now specify a new
colorproperty 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
colorEaseconfiguration 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 assine.outorquad.in, etc. If left undefined it will uselinearas default. EmitterColorOpis a brand new Emitter Op class that specifically controls the handling of color values, it extendsEmitterOpand uses the same methods but configured for faster color interpolation.- If you define
colorin your config it will override any Emitter tint values you may have set. In short, usecolorif you wish to adjust the color of the particles during their lifespan and usetintif you wish to modify either the entire emitter at once, or the color of the particles on birth only. ParticleEmitter.particleColoris a new property that allows you to get and set the particle color op value.ParticleEmitter.colorEaseis 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.sortPropertyandsortOrderAscproperties to set how (and if) particles should be sorted prior to rendering. For example, settingsortPropertytoywould 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.setSortPropertymethod allows you to modify the sort property and order at run-time. - The new
ParticleEmitter.setSortCallbackmethod 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.getBoundsmethod to return the bounds, which also gets stored in the newParticle.boundsRectangle property. ParticleEmitter.getBoundsis 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.viewBoundsis 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 newgetBoundsmethod to help define theviewBoundsarea.ParticleEmitter.overlapis 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.killis 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.getWorldTransformMatrixis a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.ParticleEmitter.worldMatrixis a new property that holds a TransformMatrix used for bounds calculations.
Particle Emitter Bounds
- Prior to v3.60 a Particle Emitter had a
boundsproperty. This was a Rectangle and if a Particle hit any of its edges it would rebound off it based on the Particlesbouncevalue. In v3.60 this action has been moved to a Particle Processor. You can still configure the bounds via the Emitter config using theboundsproperty, as before. And you can configure which faces collide via thecollideLeftetc properties. However, the following internal changes have taken place: ParticleBoundsis a new Particle Processor class that handles updating the particles.- The
ParticleEmitter.setBoundsmethod has been replaced withParticleEmitter.addParticleBoundswhich now returns a newParticleBoundsParticle Processor instance. - The
ParticleEmitter.boundsproperty has been removed. Please see theaddParticleBoundsmethod if you wish to retain this object. - The
ParticleEmitter.collideLeftproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideRightproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideTopproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideBottomproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
Particle.checkBoundsmethod has been removed as it's now handled by the Particle Processors.
Particle Processors
ParticleProcessoris 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.GravityWellnow extends the newParticleProcessorclass.ParticleEmitter.addParticleProcessoris a new method that allows you to add a Particle Processor instance to the Emitter. The oldcreateGravityWellmethod now uses this.ParticleEmitter.removeParticleProcessoris a new method that will remove a Particle Processor from an Emitter.ParticleEmitter.processorsis a new List property that contains all of the Particle Processors belonging to the Emitter.- The
ParticleEmitter.wellsproperty has been removed. You should now use the newprocessorsproperty instead, they are functionally identical. ParticleProcessor.updateis the method that handles all of the particle manipulation. It now has a new 4th parametertthat 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 viaParticleEmitter.flowCounterParticleEmitter._frameCounter- Now available viaParticleEmitter.frameCounterEmitterOp._onEmitis a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyEmitmethod, to ensure that the Emittercurrentproperty remains current.EmitterOp._onUpdateis a new private reference to the update callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyUpdatemethod, to ensure that the Emittercurrentproperty remains current.EmitterOp.destroyis a new method that nulls all references. This is called automatically when aParticleEmitteris itself destroyed.
Further Particle System Updates and Fixes:
- The Particle
DeathZone.willKillmethod now takes aParticleinstance 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.resetPositionmethod has been renamed tosetPositionand it now takes optional x/y parameters. If not given, it performs the same task asresetPositiondid in earlier versions. - The
ParticleEmitterclass now has theAlphaSingleComponent. This allows you to callsetAlphaon 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
frequencywasn'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, thepreUpdateloop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles. - Calling
ParticleEmitter.startwouldn't reset the_frameCountervalue internally, meaning the new emission didn't restart from the first texture frame again. ParticleEmitter.countersis a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous_counterand_frameCounterproperties have been merged into this array, along with new ones required for new features.- The WebGL Renderer will now use the new
setQuadfeature 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.preDestroyis 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.destroyis a new method that will clean up all external references and destroy the Animation State controller.- The
ParticleEmitter._frameLengthproperty is now specified on the class, rather than added dynamically at run-time, helping preserve class shape. - The
ParticleEmitter.defaultFrameproperty has been removed as it's not required. - Calling
ParticleEmitter.setFrameno longer resets the internal_frameCountervalue 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.configFastMapproperty has been moved to a local var within theParticleEmitterJS 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.configOpMapproperty has been moved to a local var within theParticleEmitterJS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory. Particle.sceneis a new property that references the Scene the Particle Emitter belongs to.Particle.animsis a new property that is an instance of theAnimationStatecomponent.Particle.emitis 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.isCroppedis a new read-only property. Do not modify.Particle.setSizeToFrameis a new internal NOOP method. Do not call.ParticleEmitter.animsis a new property that contains the Animation keys that can be assigned to Particles.ParticleEmitter.currentAnimis a new property that contains the index of the current animation, as tracked in cycle playback.ParticleEmitter.randomAnimis a new boolean property that controls if the animations are selected randomly, or in a cycle.ParticleEmitter.animQuantityis a new property that controls the number of consecutive particles that are emitted with the current animation.ParticleEmitter.countersis a new internal Float32Array that holds all the counters the Emitter uses.ParticleEmitter.getAnimis a new method, called by Particles when they are emitted, that will return the animation to use, if any.ParticleEmitter.setAnimis a new method, called with the Emitter Manager, that sets the animation data into the Emitter.- The
Particles.EmitterOp.toJSONmethod will now JSON stringify the property value before returning it. Particles.EmitterOp.methodis a new property that holds the current operation method being used. This is a read-only numeric value.Particles.EmitterOp.activeis 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.getMethodis a new internal method that returns the operation function being used as a numeric value. This is then cached in themethodproperty.- The
Particles.EmitterOp.setMethodsmethod 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.onChangemethod will now use the cached 'method' property to avoid running through thesetMethodsfunction 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.setConfigis a new method that allows you to set the configuration of the Emitter. Previously this was known asfromJSON.- The
ParticleEmitter.setPositionmethod no longer changes the position of the particle emission point, but of the Emitter itself. - The
ParticleEmitter.setBoundsmethod has been renamed tosetParticleBounds. - The
ParticleEmitter.setSpeedmethod has been renamed tosetParticleSpeed. - The
ParticleEmitter.setScalemethod has been renamed tosetParticleScaleassetScalewill now set the scale of the whole Emitter. - The
ParticleEmitter.setScaleXandsetScaleYmethods have been removed. Please usesetParticleScale. - The
ParticleEmitter.setGravitymethod has been renamed tosetParticleGravity. - The
ParticleEmitter.setGravityXandsetGravityYmethods have been removed. Please usesetParticleGravity. - The
ParticleEmitter.setAlphamethod has been renamed tosetParticleAlphaassetAlphawill now set the alpha of the whole Emitter. - The
ParticleEmitter.setTintmethod has been renamed tosetParticleTint. - The
ParticleEmitter.setLifespanmethod has been renamed tosetParticleLifespan. - The
ParticleEmitter.onproperty has been renamed toemittingto avoid conflicts with the Event Emitter. - The
ParticleEmitter.xproperty has been renamed toparticleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.yproperty has been renamed toparticleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleXproperty has been renamed toparticleScaleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleYproperty has been renamed toparticleScaleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.tintproperty has been renamed toparticleTintand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.alphaproperty has been renamed toparticleAlphaand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.angleproperty has been renamed toparticleAngleand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.rotateproperty has been renamed toparticleRotateand 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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
RenderTargetclass 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.clearandrebindit 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
mipmapFilterproperty 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 addmipmapFilter: '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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod is now passed the default pipeline and auto mobile setting from the Game Config.
Multi Tint Pipeline
- The
batchLinemethod 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.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
outTintEffectattribute 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.setAngularVelocityandBody.setVelocityfunctions to be timestep independent - Adds timestep independent
Body.setSpeed,Body.setAngularSpeed,Body.getSpeed,Body.getVelocityandBody.getAngularVelocity - Adds optional
updateVelocityargument toBody.setPosition,Body.setAngle,Body.translateandBody.rotate - Removes
correctionparameter fromEngine.updateas it is now built-in - Changed
Body.setAngularVelocityandBody.setVelocityto be timestep independent - Improved similarity of results between different timesteps based on
60hzas a baseline - Added timestep independent
Body.setSpeed,Body.setAngularSpeed,Body.getSpeed,Body.getVelocity,Body.getAngularVelocity - Added optional
updateVelocityargument toBody.setPosition,Body.setAngle,Body.translate,Body.rotate - Added extended documentation for
Body.applyForce - Moved time correction feature from
Engine.updateto be built-in toMatter.Body - Added readonly
body.deltaTimeproperty - Added
speedsetters toBody.set - Added
updateVelocityargument toBody.setPosition,Body.setAngle,Body.translateandBody.rotate - Changed engine
collisionStartevent 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.pointAWorldandConstraint.pointBWorld - Improved
Body.applyForcedocs - 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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. This should give most developers the same level of sequencing they had using Timelines, without the timing issues. - The
Tween.seekmethod 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 newseekmethod 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.originis now (0.5, 0.5) by default instead of (0, 0).The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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:
PostPipelineis a new Game Object Component that is now inherited by all Game Objects that are capable of using it.- Game Objects with the
PostPipelinecomponent now have a new property calledpostPipelineData. This object is used for storing Post Pipeline specific data in. Previously, both regular and post pipelines used the samepipelineDataobject, but this has now been split up for flexibility. - The
Pipeline.resetPipelinemethod no longer has its firstresetPostPipelinesargument. It now has just one argumentresetDataso please be aware of this if you call this function anywhere in your code. PostPipeline.initPostPipelineis a new method that should be called by any Game Object that supports Post Pipelines.- The following Game Objects now have the new
PostPipelineComponent exclusively:ContainerandLayer.
Input System Updates
There are breaking changes from previous versions of Phaser.
- The
InteractiveObject.alwaysEnabledproperty has been removed. It is no longer checked within theInputPluginand 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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow hands over most control of the framebuffers to the WebGLRenderer. - The
GameObjects.Components.Mask.createBitmapMaskmethod can now accept thex,y,textureandframeparameters new to the BitmapMask constructor. - Previously, calling
createBitmapMaskon 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue 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-evenandstaggeraxis-x, staggerindex-even(thanks @rexrainbow) - The Arcade Physics World has a new property
tileFilterOptionswhich is an object passed to theGetTilesWithinmethods 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.strokeRoundedRectandfillRoundedRectmethods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow) AnimationManager.getAnimsFromTextureis 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.setLineSpacingis 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 alsoBitmapText.lineSpacingfor the property rather than the method.WebGLPipeline.vertexAvailableis a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.- The
TilemapandTilemapLayerclasses have a new methodgetTileCorners. 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.getAllPlayingis a new method that will return all currently playing sounds in the Sound Manager.Animation.showBeforeDelayis 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.resetPointersis 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.resetis a new method that will reset a Pointer instance back to its 'factory' settings.- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.Game.isPausedis a new boolean that tracks if the Game loop is paused, or not (and can also be toggled directly)ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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
AnimationManagerandAnimationStateif you try to add an animation with a key that already exists. Fix #6434. Tilemap.addTilesetImagehas a new optional parametertileOffsetwhich, 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.getBoundsmethod will now return aGeom.Rectangleinstance, rather than a plain Object (thanks @samme) - The
GetBounds.getCentermethod now has an optionalincludeParentargument, which allows you to get the value in world space. - The
MatterTileBodyclass, which is created when you convert a Tilemap into a Matter Physics world, will now check to see if the Tile hasflipXorflipYset on it and rotate the body accordingly. Fix #5893 (thanks @Olliebrown @phaserhelp) - The
BaseCamerahas had itsAlphacomponent replaced withAlphaSingle. Previously you had access to properties such asalphaTopLeftthat never worked, now it correctly has just a single alpha property (thanks @samme) Time.Clock.startTimeis 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._matrixand_dataare now Float32Arrays.- Calling the
ColorMatrix.set,resetandgetDatamethods all now use the built-in Float32 Array operations, making them considerably faster. ColorMatrix.BLACK_WHITEis a new constant used by blackwhite operations.ColorMatrix.NEGATIVEis a new constant used by negative operations.ColorMatrix.DESATURATE_LUMINANCEis a new constant used by desaturation operations.ColorMatrix.SEPIAis a new constant used by sepia operations.ColorMatrix.LSDis a new constant used by LSD operations.ColorMatrix.BROWNis a new constant used by brown operations.ColorMatrix.VINTAGEis a new constant used by vintage pinhole operations.ColorMatrix.KODACHROMEis a new constant used by kodachrome operations.ColorMatrix.TECHNICOLORis a new constant used by technicolor operations.ColorMatrix.POLAROIDis a new constant used by polaroid operations.ColorMatrix.SHIFT_BGRis 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.haswill now return a strict boolean, rather than an object that can be cooerced into a boolean (thanks @samme)- The
CanvasTexture.drawmethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
CanvasTexture.drawFramemethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
CanvasTexture.clearmethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
Game.registry, which is aDataManagerinstance 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
GenerateVertsfunction has a new optional parameterflipUVwhich, if set, will flip the UV texture coordinates (thanks cedarcantab) - The
GenerateVertsfunction no longer errors if the verts and uvs arrays are not the same size andcontainsZis true (thanks cedarcantab) - The
Device.Browserchecks 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.processQueuemethod will no longerreturnif 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.scrollXandscrollYwill now only set theCamera.dirtyflag totrueif 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.updateis a new method that updates each of the Face vertices. This is now called internally byFace.isInView.Vertex.resizeis a new method that will set the position and then translate the Vertex based on an identity matrix.- The
Vertex.updatemethod now returnsthisto allow it to be chained. - You can now optionally specify the
maxSpeedvalue in the Arcade Physics Group config (thanks @samme) - You can now optionally specify the
useDampingboolean in the Arcade Physics Group config (thanks @samme) - Removed the
HexagonalTileToWorldYfunction as it cannot work without an X coordinate. UseHexagonalTileToWorldXYinstead. - Removed the
HexagonalWorldToTileYfunction as it cannot work without an X coordinate. UseHexagonalWorldToTileXYinstead. - 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.getAllmethod used to require akeyparameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned. - The
WebAudioSoundManagerwill 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_RESTOREDGame Event has been removed and the WebGL Renderer no longer listens for thecontextrestoredDOM event, or has acontextRestoredHandlermethod. 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
TextandTileSpriteGame Objects no longer listen for theCONTEXT_RESTOREDevent and have had theironContextRestoredmethods removed. Scenes.Systems.canInputis a new internal method that determines if a Scene can receive Input events, or not. This is now used by theInputPlugininstead of the previousisActivetest. This allows a Scene to emit and handle input events even when it is runninginitorpreload. Previously, it could only do this aftercreatehad finished running. Fix #6123 (thanks @yaasinhamidi)- The
BitmapTextGame Object has two new read-only propertiesdisplayWidthanddisplayHeight. This allows the BitmapText to correctly use theGetBoundscomponent. - The
BitmapTextGame Object now has theGetBoundscomponent added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames) WebGLSnapshotwill 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.snapshotFramebufferand 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 methodsnapshotAreahas had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)Animation.stopis always called when a new animation is loaded, regardless if the animation was playing or not and thedelayCounteris reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)ScaleManager.listenershas been renamed todomlistenersto avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)Geom.Intersects.LineToLinewill no longer create an internalPointobject, as it's not required internally (thanks @Trissolo)- The
tempZoneused byGridAlignhas now hadsetOrigin(0, 0)applied to it. This leads to more accurate / expected zone placement when aligning grid items. - The
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill 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,lsdand 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.addGlowadds a Glow Pre FX effect to the Game Object.GameObject.preFX.addShadowadds a Shadow Pre FX effect to the Game Object.GameObject.preFX.addPixelateadds a Pixelate Pre FX effect to the Game Object.GameObject.preFX.addVignetteadds a Vignette Pre FX effect to the Game Object.GameObject.preFX.addShineadds a Shine Pre FX effect to the Game Object.GameObject.preFX.addBluradds a Blur Pre FX effect to the Game Object.GameObject.preFX.addGradientadds a Gradient Pre FX effect to the Game Object.GameObject.preFX.addBloomadds a Bloom Pre FX effect to the Game Object.GameObject.preFX.addColorMatrixadds a ColorMatrix Pre FX effect to the Game Object.GameObject.preFX.addCircleadds a Circle Pre FX effect to the Game Object.GameObject.preFX.addBarreladds a Barrel Pre FX effect to the Game Object.GameObject.preFX.addDisplacementadds a Displacement Pre FX effect to the Game Object.GameObject.preFX.addWipeadds a Wipe Pre FX effect to the Game Object.GameObject.preFX.addRevealadds a Reveal Pre FX effect to the Game Object.GameObject.preFX.addBokehadds a Bokeh Pre FX effect to the Game Object.GameObject.preFX.addTiltShiftadds a TiltShift Pre FX effect to the Game Object.
Available to all Game Objects:
GameObject.postFX.addGlowadds a Glow Post FX effect to the Game Object.GameObject.postFX.addShadowadds a Shadow Post FX effect to the Game Object.GameObject.postFX.addPixelateadds a Pixelate Post FX effect to the Game Object.GameObject.postFX.addVignetteadds a Vignette Post FX effect to the Game Object.GameObject.postFX.addShineadds a Shine Post FX effect to the Game Object.GameObject.postFX.addBluradds a Blur Post FX effect to the Game Object.GameObject.postFX.addGradientadds a Gradient Post FX effect to the Game Object.GameObject.postFX.addBloomadds a Bloom Post FX effect to the Game Object.GameObject.postFX.addColorMatrixadds a ColorMatrix Post FX effect to the Game Object.GameObject.postFX.addCircleadds a Circle Post FX effect to the Game Object.GameObject.postFX.addBarreladds a Barrel Post FX effect to the Game Object.GameObject.postFX.addDisplacementadds a Displacement Post FX effect to the Game Object.GameObject.postFX.addWipeadds a Wipe Post FX effect to the Game Object.GameObject.postFX.addRevealadds a Reveal Post FX effect to the Game Object.GameObject.postFX.addBokehadds a Bokeh Post FX effect to the Game Object.GameObject.postFX.addTiltShiftadds 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
drawDebugon 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
addandmakefunctions 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 (viaaddToScene: 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
SpineFileloader has now been updated so that the always-unique Spine key is pre-pended to the filename, for example if the key wasbonusand the PNG in the atlas wascoin.pngthen the final key (as stored in the Texture Manager) is nowbonus:coin.png. TheSpinePlugin.getAtlasCanvasandgetAtlasWebGLmethods have been updated to reflect this change. Fix #6022 (thanks @orjandh) - If a
SpineContainerhad 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isPreFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allPreFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Pre FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.- The
WebGLPipeline.setTimemethod has a new optional parametershader, which allows you to control the shader on which the time value is set. - If you add
#define SHADER_NAMEto the start of your shader then it will be picked up as theWebGLShadername during thesetShadersFromConfigprocess withinWebGLPipeline. - Calling
setPostPipelineon a Game Object will now pass thepipelineDataconfiguration object (if provided) to the pipeline instance being created. PipelineManager.getPostPipelinenow has an optional 3rd parameter, aconfigobject 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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
advanceproperty, or by calling the newParticleEmitter.fastForwardmethod. 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.startmethod has a new optional parameteradvancethat 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.durationis a new property that contains the duration that the Emitter will emit particles for in flow mode.- The
ParticleEmitter.startmethod has a new optional parameterduration, 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.stopmethod has a new optional parameterkill. 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
stopAfterproperty. This, combined with thefrequencyproperty 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
stopAftercounter is reset each time you call thestartorflowmethods.
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
holdconfiguration 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.STARTevent is fired whenever the Emitter begins emission of particles in flow mode. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.EXPLODEevent is fired whenever the Emitter explodes a bunch of particles via theexplodemethod. A reference to theParticleEmitterand a reference to the most recently firedParticleinstance are the two parameters. - The
Particles.Events.DEATH_ZONEevent is fired whenever a Particle is killed by a Death Zone. A reference to theParticleEmitter, the killedParticleand theDeathZonethat caused it are the 3 parameters. - The
Particles.Events.STOPevent is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call thestopmethod, or when an Emitter hits its duration or stopAfter limit. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.COMPLETEevent 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.addEmitZonemethod:
```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
totalproperty.EdgeZone.totalandRandomZone.totalare 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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeEmitZoneis a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getEmitZoneis a new method that Particles call when they are 'fired' in order to set their starting position, if any.- The property
ParticleEmitter.emitZonehas been removed. It has been replaced with the newParticleEmitter.emitZonesarray-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.addDeathZonemethod:
```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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeDeathZoneis a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getDeathZoneis 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.deathZonehas been removed. It has been replaced with the newParticleEmitter.deathZonesarray-based property.
Particle Colors
- You can now specify a new
colorproperty 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
colorEaseconfiguration 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 assine.outorquad.in, etc. If left undefined it will uselinearas default. EmitterColorOpis a brand new Emitter Op class that specifically controls the handling of color values, it extendsEmitterOpand uses the same methods but configured for faster color interpolation.- If you define
colorin your config it will override any Emitter tint values you may have set. In short, usecolorif you wish to adjust the color of the particles during their lifespan and usetintif you wish to modify either the entire emitter at once, or the color of the particles on birth only. ParticleEmitter.particleColoris a new property that allows you to get and set the particle color op value.ParticleEmitter.colorEaseis 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.sortPropertyandsortOrderAscproperties to set how (and if) particles should be sorted prior to rendering. For example, settingsortPropertytoywould 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.setSortPropertymethod allows you to modify the sort property and order at run-time. - The new
ParticleEmitter.setSortCallbackmethod 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.getBoundsmethod to return the bounds, which also gets stored in the newParticle.boundsRectangle property. ParticleEmitter.getBoundsis 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.viewBoundsis 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 newgetBoundsmethod to help define theviewBoundsarea.ParticleEmitter.overlapis 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.killis 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.getWorldTransformMatrixis a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.ParticleEmitter.worldMatrixis a new property that holds a TransformMatrix used for bounds calculations.
Particle Emitter Bounds
- Prior to v3.60 a Particle Emitter had a
boundsproperty. This was a Rectangle and if a Particle hit any of its edges it would rebound off it based on the Particlesbouncevalue. In v3.60 this action has been moved to a Particle Processor. You can still configure the bounds via the Emitter config using theboundsproperty, as before. And you can configure which faces collide via thecollideLeftetc properties. However, the following internal changes have taken place: ParticleBoundsis a new Particle Processor class that handles updating the particles.- The
ParticleEmitter.setBoundsmethod has been replaced withParticleEmitter.addParticleBoundswhich now returns a newParticleBoundsParticle Processor instance. - The
ParticleEmitter.boundsproperty has been removed. Please see theaddParticleBoundsmethod if you wish to retain this object. - The
ParticleEmitter.collideLeftproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideRightproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideTopproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideBottomproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
Particle.checkBoundsmethod has been removed as it's now handled by the Particle Processors.
Particle Processors
ParticleProcessoris 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.GravityWellnow extends the newParticleProcessorclass.ParticleEmitter.addParticleProcessoris a new method that allows you to add a Particle Processor instance to the Emitter. The oldcreateGravityWellmethod now uses this.ParticleEmitter.removeParticleProcessoris a new method that will remove a Particle Processor from an Emitter.ParticleEmitter.processorsis a new List property that contains all of the Particle Processors belonging to the Emitter.- The
ParticleEmitter.wellsproperty has been removed. You should now use the newprocessorsproperty instead, they are functionally identical. ParticleProcessor.updateis the method that handles all of the particle manipulation. It now has a new 4th parametertthat 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 viaParticleEmitter.flowCounterParticleEmitter._frameCounter- Now available viaParticleEmitter.frameCounterEmitterOp._onEmitis a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyEmitmethod, to ensure that the Emittercurrentproperty remains current.EmitterOp._onUpdateis a new private reference to the update callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyUpdatemethod, to ensure that the Emittercurrentproperty remains current.EmitterOp.destroyis a new method that nulls all references. This is called automatically when aParticleEmitteris itself destroyed.
Further Particle System Updates and Fixes:
- The Particle
DeathZone.willKillmethod now takes aParticleinstance 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.resetPositionmethod has been renamed tosetPositionand it now takes optional x/y parameters. If not given, it performs the same task asresetPositiondid in earlier versions. - The
ParticleEmitterclass now has theAlphaSingleComponent. This allows you to callsetAlphaon 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
frequencywasn'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, thepreUpdateloop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles. - Calling
ParticleEmitter.startwouldn't reset the_frameCountervalue internally, meaning the new emission didn't restart from the first texture frame again. ParticleEmitter.countersis a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous_counterand_frameCounterproperties have been merged into this array, along with new ones required for new features.- The WebGL Renderer will now use the new
setQuadfeature 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.preDestroyis 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.destroyis a new method that will clean up all external references and destroy the Animation State controller.- The
ParticleEmitter._frameLengthproperty is now specified on the class, rather than added dynamically at run-time, helping preserve class shape. - The
ParticleEmitter.defaultFrameproperty has been removed as it's not required. - Calling
ParticleEmitter.setFrameno longer resets the internal_frameCountervalue 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.configFastMapproperty has been moved to a local var within theParticleEmitterJS 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.configOpMapproperty has been moved to a local var within theParticleEmitterJS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory. Particle.sceneis a new property that references the Scene the Particle Emitter belongs to.Particle.animsis a new property that is an instance of theAnimationStatecomponent.Particle.emitis 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.isCroppedis a new read-only property. Do not modify.Particle.setSizeToFrameis a new internal NOOP method. Do not call.ParticleEmitter.animsis a new property that contains the Animation keys that can be assigned to Particles.ParticleEmitter.currentAnimis a new property that contains the index of the current animation, as tracked in cycle playback.ParticleEmitter.randomAnimis a new boolean property that controls if the animations are selected randomly, or in a cycle.ParticleEmitter.animQuantityis a new property that controls the number of consecutive particles that are emitted with the current animation.ParticleEmitter.countersis a new internal Float32Array that holds all the counters the Emitter uses.ParticleEmitter.getAnimis a new method, called by Particles when they are emitted, that will return the animation to use, if any.ParticleEmitter.setAnimis a new method, called with the Emitter Manager, that sets the animation data into the Emitter.- The
Particles.EmitterOp.toJSONmethod will now JSON stringify the property value before returning it. Particles.EmitterOp.methodis a new property that holds the current operation method being used. This is a read-only numeric value.Particles.EmitterOp.activeis 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.getMethodis a new internal method that returns the operation function being used as a numeric value. This is then cached in themethodproperty.- The
Particles.EmitterOp.setMethodsmethod 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.onChangemethod will now use the cached 'method' property to avoid running through thesetMethodsfunction 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.setConfigis a new method that allows you to set the configuration of the Emitter. Previously this was known asfromJSON.- The
ParticleEmitter.setPositionmethod no longer changes the position of the particle emission point, but of the Emitter itself. - The
ParticleEmitter.setBoundsmethod has been renamed tosetParticleBounds. - The
ParticleEmitter.setSpeedmethod has been renamed tosetParticleSpeed. - The
ParticleEmitter.setScalemethod has been renamed tosetParticleScaleassetScalewill now set the scale of the whole Emitter. - The
ParticleEmitter.setScaleXandsetScaleYmethods have been removed. Please usesetParticleScale. - The
ParticleEmitter.setGravitymethod has been renamed tosetParticleGravity. - The
ParticleEmitter.setGravityXandsetGravityYmethods have been removed. Please usesetParticleGravity. - The
ParticleEmitter.setAlphamethod has been renamed tosetParticleAlphaassetAlphawill now set the alpha of the whole Emitter. - The
ParticleEmitter.setTintmethod has been renamed tosetParticleTint. - The
ParticleEmitter.setLifespanmethod has been renamed tosetParticleLifespan. - The
ParticleEmitter.onproperty has been renamed toemittingto avoid conflicts with the Event Emitter. - The
ParticleEmitter.xproperty has been renamed toparticleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.yproperty has been renamed toparticleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleXproperty has been renamed toparticleScaleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleYproperty has been renamed toparticleScaleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.tintproperty has been renamed toparticleTintand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.alphaproperty has been renamed toparticleAlphaand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.angleproperty has been renamed toparticleAngleand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.rotateproperty has been renamed toparticleRotateand 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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
RenderTargetclass 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.clearandrebindit 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
mipmapFilterproperty 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 addmipmapFilter: '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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod is now passed the default pipeline and auto mobile setting from the Game Config.
Multi Tint Pipeline
- The
batchLinemethod 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.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
outTintEffectattribute 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. This should give most developers the same level of sequencing they had using Timelines, without the timing issues. - The
Tween.seekmethod 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 newseekmethod 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.originis now (0.5, 0.5) by default instead of (0, 0).The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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:
PostPipelineis a new Game Object Component that is now inherited by all Game Objects that are capable of using it.- Game Objects with the
PostPipelinecomponent now have a new property calledpostPipelineData. This object is used for storing Post Pipeline specific data in. Previously, both regular and post pipelines used the samepipelineDataobject, but this has now been split up for flexibility. - The
Pipeline.resetPipelinemethod no longer has its firstresetPostPipelinesargument. It now has just one argumentresetDataso please be aware of this if you call this function anywhere in your code. PostPipeline.initPostPipelineis a new method that should be called by any Game Object that supports Post Pipelines.- The following Game Objects now have the new
PostPipelineComponent exclusively:ContainerandLayer.
Input System Updates
There are breaking changes from previous versions of Phaser.
- The
InteractiveObject.alwaysEnabledproperty has been removed. It is no longer checked within theInputPluginand 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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow hands over most control of the framebuffers to the WebGLRenderer. - The
GameObjects.Components.Mask.createBitmapMaskmethod can now accept thex,y,textureandframeparameters new to the BitmapMask constructor. - Previously, calling
createBitmapMaskon 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue 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-evenandstaggeraxis-x, staggerindex-even(thanks @rexrainbow) - The Arcade Physics World has a new property
tileFilterOptionswhich is an object passed to theGetTilesWithinmethods 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.strokeRoundedRectandfillRoundedRectmethods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow) AnimationManager.getAnimsFromTextureis 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.setLineSpacingis 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 alsoBitmapText.lineSpacingfor the property rather than the method.WebGLPipeline.vertexAvailableis a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.- The
TilemapandTilemapLayerclasses have a new methodgetTileCorners. 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.getAllPlayingis a new method that will return all currently playing sounds in the Sound Manager.Animation.showBeforeDelayis 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.resetPointersis 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.resetis a new method that will reset a Pointer instance back to its 'factory' settings.- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.Game.isPausedis a new boolean that tracks if the Game loop is paused, or not (and can also be toggled directly)ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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
AnimationManagerandAnimationStateif you try to add an animation with a key that already exists. Fix #6434. Tilemap.addTilesetImagehas a new optional parametertileOffsetwhich, 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.getBoundsmethod will now return aGeom.Rectangleinstance, rather than a plain Object (thanks @samme) - The
GetBounds.getCentermethod now has an optionalincludeParentargument, which allows you to get the value in world space. - The
MatterTileBodyclass, which is created when you convert a Tilemap into a Matter Physics world, will now check to see if the Tile hasflipXorflipYset on it and rotate the body accordingly. Fix #5893 (thanks @Olliebrown @phaserhelp) - The
BaseCamerahas had itsAlphacomponent replaced withAlphaSingle. Previously you had access to properties such asalphaTopLeftthat never worked, now it correctly has just a single alpha property (thanks @samme) Time.Clock.startTimeis 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._matrixand_dataare now Float32Arrays.- Calling the
ColorMatrix.set,resetandgetDatamethods all now use the built-in Float32 Array operations, making them considerably faster. ColorMatrix.BLACK_WHITEis a new constant used by blackwhite operations.ColorMatrix.NEGATIVEis a new constant used by negative operations.ColorMatrix.DESATURATE_LUMINANCEis a new constant used by desaturation operations.ColorMatrix.SEPIAis a new constant used by sepia operations.ColorMatrix.LSDis a new constant used by LSD operations.ColorMatrix.BROWNis a new constant used by brown operations.ColorMatrix.VINTAGEis a new constant used by vintage pinhole operations.ColorMatrix.KODACHROMEis a new constant used by kodachrome operations.ColorMatrix.TECHNICOLORis a new constant used by technicolor operations.ColorMatrix.POLAROIDis a new constant used by polaroid operations.ColorMatrix.SHIFT_BGRis 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.haswill now return a strict boolean, rather than an object that can be cooerced into a boolean (thanks @samme)- The
CanvasTexture.drawmethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
CanvasTexture.drawFramemethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
CanvasTexture.clearmethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
Game.registry, which is aDataManagerinstance 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
GenerateVertsfunction has a new optional parameterflipUVwhich, if set, will flip the UV texture coordinates (thanks cedarcantab) - The
GenerateVertsfunction no longer errors if the verts and uvs arrays are not the same size andcontainsZis true (thanks cedarcantab) - The
Device.Browserchecks 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.processQueuemethod will no longerreturnif 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.scrollXandscrollYwill now only set theCamera.dirtyflag totrueif 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.updateis a new method that updates each of the Face vertices. This is now called internally byFace.isInView.Vertex.resizeis a new method that will set the position and then translate the Vertex based on an identity matrix.- The
Vertex.updatemethod now returnsthisto allow it to be chained. - You can now optionally specify the
maxSpeedvalue in the Arcade Physics Group config (thanks @samme) - You can now optionally specify the
useDampingboolean in the Arcade Physics Group config (thanks @samme) - Removed the
HexagonalTileToWorldYfunction as it cannot work without an X coordinate. UseHexagonalTileToWorldXYinstead. - Removed the
HexagonalWorldToTileYfunction as it cannot work without an X coordinate. UseHexagonalWorldToTileXYinstead. - 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.getAllmethod used to require akeyparameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned. - The
WebAudioSoundManagerwill 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_RESTOREDGame Event has been removed and the WebGL Renderer no longer listens for thecontextrestoredDOM event, or has acontextRestoredHandlermethod. 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
TextandTileSpriteGame Objects no longer listen for theCONTEXT_RESTOREDevent and have had theironContextRestoredmethods removed. Scenes.Systems.canInputis a new internal method that determines if a Scene can receive Input events, or not. This is now used by theInputPlugininstead of the previousisActivetest. This allows a Scene to emit and handle input events even when it is runninginitorpreload. Previously, it could only do this aftercreatehad finished running. Fix #6123 (thanks @yaasinhamidi)- The
BitmapTextGame Object has two new read-only propertiesdisplayWidthanddisplayHeight. This allows the BitmapText to correctly use theGetBoundscomponent. - The
BitmapTextGame Object now has theGetBoundscomponent added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames) WebGLSnapshotwill 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.snapshotFramebufferand 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 methodsnapshotAreahas had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)Animation.stopis always called when a new animation is loaded, regardless if the animation was playing or not and thedelayCounteris reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)ScaleManager.listenershas been renamed todomlistenersto avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)Geom.Intersects.LineToLinewill no longer create an internalPointobject, as it's not required internally (thanks @Trissolo)- The
tempZoneused byGridAlignhas now hadsetOrigin(0, 0)applied to it. This leads to more accurate / expected zone placement when aligning grid items. - The
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- The
TilemapLayer.skipCullfeature wasn't being applied correctly for Isometric, Hexagonal or Staggered tiles, only for Orthographic tiles (the default). It will now respect theskipCullproperty and return all tiles during culling if enabled. Fix #5524 (thanks @veleek) - Shutting down a Scene that didn't have the
LoaderPluginwould throw an error when removing event handlers. It now checks first, before removing (thanks @samme) - The
Container.getBoundsmethod will now usegetTextBoundsif one of its children is aBitmapTextGame Object, giving more accurate bounds results (thanks @EmilSV) - The
renderFlagsproperty, used to determine if a Game Object will render, or not, would be calculated incorrectly depending on the order of thescaleXandscaleYproperties. It now works regardless of the order (thanks @mizunokazumi) - The
SpriteSheetFromAtlasparser was using the incorrectsourceIndexto 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
maxSpeedsetting 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.jsentry 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_UPDATEevent from firing after the transition is over. Fix #5550 (thanks @mijinc0 @samme) - Although not recommended, when adding a
LayerGame Object to anotherLayerGame Object, it will no longer error because it cannot find theremoveFromDisplayListfunction. Fix #5595 (thanks @tringcooler) - The
Actions.Spreadmethod will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV) - Calling
setDisplayOriginon aVideoGame Object would cause the origins to be set toNaNif 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
ImageFileloads 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
dataKeyto specify a part of a JSON file when usingload.packwould 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.advancedWordWrapfunction 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
HexagonalTileToWorldXYfunction as it was incorrect. Now returns world coordinates correctly. Tilemap.copywould 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.copywill now use theDeepCopyfunction to copy theTile.propertiesobject, as otherwise it just gets copied by reference.- Recoded the point conversion math in the
HexagonalWorldToTileXYfunction as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich) - Fixed the point conversion math in the
IsometricWorldToTileXYfunction 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.worldToTileXorworldToTileYon a Isometric or Hexagonal Tilemap will now always returnnullinstead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should useworldToTileXYinstead. - The
Game.headlessStepmethod will now resetSceneManager.isProcessingbeforePRE_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.setPointswas called with the exact same number of points as before, it wouldn't set thedirtyflag, meaning the vertices were not updated on the next render (thanks @stupot) Particle.firewill 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)
TextGame 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.destroyLayermethod would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme) MapDataandObjectLayerwill now enforce that theTilemap.objectsproperty 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
ParseJSONTiledfunction will now run aDeepCopyon 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,lsdand 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.addGlowadds a Glow Pre FX effect to the Game Object.GameObject.preFX.addShadowadds a Shadow Pre FX effect to the Game Object.GameObject.preFX.addPixelateadds a Pixelate Pre FX effect to the Game Object.GameObject.preFX.addVignetteadds a Vignette Pre FX effect to the Game Object.GameObject.preFX.addShineadds a Shine Pre FX effect to the Game Object.GameObject.preFX.addBluradds a Blur Pre FX effect to the Game Object.GameObject.preFX.addGradientadds a Gradient Pre FX effect to the Game Object.GameObject.preFX.addBloomadds a Bloom Pre FX effect to the Game Object.GameObject.preFX.addColorMatrixadds a ColorMatrix Pre FX effect to the Game Object.GameObject.preFX.addCircleadds a Circle Pre FX effect to the Game Object.GameObject.preFX.addBarreladds a Barrel Pre FX effect to the Game Object.GameObject.preFX.addDisplacementadds a Displacement Pre FX effect to the Game Object.GameObject.preFX.addWipeadds a Wipe Pre FX effect to the Game Object.GameObject.preFX.addRevealadds a Reveal Pre FX effect to the Game Object.GameObject.preFX.addBokehadds a Bokeh Pre FX effect to the Game Object.GameObject.preFX.addTiltShiftadds a TiltShift Pre FX effect to the Game Object.
Available to all Game Objects:
GameObject.postFX.addGlowadds a Glow Post FX effect to the Game Object.GameObject.postFX.addShadowadds a Shadow Post FX effect to the Game Object.GameObject.postFX.addPixelateadds a Pixelate Post FX effect to the Game Object.GameObject.postFX.addVignetteadds a Vignette Post FX effect to the Game Object.GameObject.postFX.addShineadds a Shine Post FX effect to the Game Object.GameObject.postFX.addBluradds a Blur Post FX effect to the Game Object.GameObject.postFX.addGradientadds a Gradient Post FX effect to the Game Object.GameObject.postFX.addBloomadds a Bloom Post FX effect to the Game Object.GameObject.postFX.addColorMatrixadds a ColorMatrix Post FX effect to the Game Object.GameObject.postFX.addCircleadds a Circle Post FX effect to the Game Object.GameObject.postFX.addBarreladds a Barrel Post FX effect to the Game Object.GameObject.postFX.addDisplacementadds a Displacement Post FX effect to the Game Object.GameObject.postFX.addWipeadds a Wipe Post FX effect to the Game Object.GameObject.postFX.addRevealadds a Reveal Post FX effect to the Game Object.GameObject.postFX.addBokehadds a Bokeh Post FX effect to the Game Object.GameObject.postFX.addTiltShiftadds 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
drawDebugon 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
addandmakefunctions 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 (viaaddToScene: 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
SpineFileloader has now been updated so that the always-unique Spine key is pre-pended to the filename, for example if the key wasbonusand the PNG in the atlas wascoin.pngthen the final key (as stored in the Texture Manager) is nowbonus:coin.png. TheSpinePlugin.getAtlasCanvasandgetAtlasWebGLmethods have been updated to reflect this change. Fix #6022 (thanks @orjandh) - If a
SpineContainerhad 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isPreFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allPreFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Pre FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.- The
WebGLPipeline.setTimemethod has a new optional parametershader, which allows you to control the shader on which the time value is set. - If you add
#define SHADER_NAMEto the start of your shader then it will be picked up as theWebGLShadername during thesetShadersFromConfigprocess withinWebGLPipeline. - Calling
setPostPipelineon a Game Object will now pass thepipelineDataconfiguration object (if provided) to the pipeline instance being created. PipelineManager.getPostPipelinenow has an optional 3rd parameter, aconfigobject 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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
advanceproperty, or by calling the newParticleEmitter.fastForwardmethod. 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.startmethod has a new optional parameteradvancethat 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.durationis a new property that contains the duration that the Emitter will emit particles for in flow mode.- The
ParticleEmitter.startmethod has a new optional parameterduration, 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.stopmethod has a new optional parameterkill. 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
stopAfterproperty. This, combined with thefrequencyproperty 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
stopAftercounter is reset each time you call thestartorflowmethods.
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
holdconfiguration 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.STARTevent is fired whenever the Emitter begins emission of particles in flow mode. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.EXPLODEevent is fired whenever the Emitter explodes a bunch of particles via theexplodemethod. A reference to theParticleEmitterand a reference to the most recently firedParticleinstance are the two parameters. - The
Particles.Events.DEATH_ZONEevent is fired whenever a Particle is killed by a Death Zone. A reference to theParticleEmitter, the killedParticleand theDeathZonethat caused it are the 3 parameters. - The
Particles.Events.STOPevent is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call thestopmethod, or when an Emitter hits its duration or stopAfter limit. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.COMPLETEevent 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.addEmitZonemethod:
```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
totalproperty.EdgeZone.totalandRandomZone.totalare 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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeEmitZoneis a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getEmitZoneis a new method that Particles call when they are 'fired' in order to set their starting position, if any.- The property
ParticleEmitter.emitZonehas been removed. It has been replaced with the newParticleEmitter.emitZonesarray-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.addDeathZonemethod:
```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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeDeathZoneis a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getDeathZoneis 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.deathZonehas been removed. It has been replaced with the newParticleEmitter.deathZonesarray-based property.
Particle Colors
- You can now specify a new
colorproperty 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
colorEaseconfiguration 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 assine.outorquad.in, etc. If left undefined it will uselinearas default. EmitterColorOpis a brand new Emitter Op class that specifically controls the handling of color values, it extendsEmitterOpand uses the same methods but configured for faster color interpolation.- If you define
colorin your config it will override any Emitter tint values you may have set. In short, usecolorif you wish to adjust the color of the particles during their lifespan and usetintif you wish to modify either the entire emitter at once, or the color of the particles on birth only. ParticleEmitter.particleColoris a new property that allows you to get and set the particle color op value.ParticleEmitter.colorEaseis 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.sortPropertyandsortOrderAscproperties to set how (and if) particles should be sorted prior to rendering. For example, settingsortPropertytoywould 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.setSortPropertymethod allows you to modify the sort property and order at run-time. - The new
ParticleEmitter.setSortCallbackmethod 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.getBoundsmethod to return the bounds, which also gets stored in the newParticle.boundsRectangle property. ParticleEmitter.getBoundsis 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.viewBoundsis 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 newgetBoundsmethod to help define theviewBoundsarea.ParticleEmitter.overlapis 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.killis 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.getWorldTransformMatrixis a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.ParticleEmitter.worldMatrixis a new property that holds a TransformMatrix used for bounds calculations.
Particle Emitter Bounds
- Prior to v3.60 a Particle Emitter had a
boundsproperty. This was a Rectangle and if a Particle hit any of its edges it would rebound off it based on the Particlesbouncevalue. In v3.60 this action has been moved to a Particle Processor. You can still configure the bounds via the Emitter config using theboundsproperty, as before. And you can configure which faces collide via thecollideLeftetc properties. However, the following internal changes have taken place: ParticleBoundsis a new Particle Processor class that handles updating the particles.- The
ParticleEmitter.setBoundsmethod has been replaced withParticleEmitter.addParticleBoundswhich now returns a newParticleBoundsParticle Processor instance. - The
ParticleEmitter.boundsproperty has been removed. Please see theaddParticleBoundsmethod if you wish to retain this object. - The
ParticleEmitter.collideLeftproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideRightproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideTopproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideBottomproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
Particle.checkBoundsmethod has been removed as it's now handled by the Particle Processors.
Particle Processors
ParticleProcessoris 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.GravityWellnow extends the newParticleProcessorclass.ParticleEmitter.addParticleProcessoris a new method that allows you to add a Particle Processor instance to the Emitter. The oldcreateGravityWellmethod now uses this.ParticleEmitter.removeParticleProcessoris a new method that will remove a Particle Processor from an Emitter.ParticleEmitter.processorsis a new List property that contains all of the Particle Processors belonging to the Emitter.- The
ParticleEmitter.wellsproperty has been removed. You should now use the newprocessorsproperty instead, they are functionally identical. ParticleProcessor.updateis the method that handles all of the particle manipulation. It now has a new 4th parametertthat 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 viaParticleEmitter.flowCounterParticleEmitter._frameCounter- Now available viaParticleEmitter.frameCounterEmitterOp._onEmitis a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyEmitmethod, to ensure that the Emittercurrentproperty remains current.EmitterOp._onUpdateis a new private reference to the update callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyUpdatemethod, to ensure that the Emittercurrentproperty remains current.EmitterOp.destroyis a new method that nulls all references. This is called automatically when aParticleEmitteris itself destroyed.
Further Particle System Updates and Fixes:
- The Particle
DeathZone.willKillmethod now takes aParticleinstance 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.resetPositionmethod has been renamed tosetPositionand it now takes optional x/y parameters. If not given, it performs the same task asresetPositiondid in earlier versions. - The
ParticleEmitterclass now has theAlphaSingleComponent. This allows you to callsetAlphaon 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
frequencywasn'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, thepreUpdateloop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles. - Calling
ParticleEmitter.startwouldn't reset the_frameCountervalue internally, meaning the new emission didn't restart from the first texture frame again. ParticleEmitter.countersis a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous_counterand_frameCounterproperties have been merged into this array, along with new ones required for new features.- The WebGL Renderer will now use the new
setQuadfeature 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.preDestroyis 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.destroyis a new method that will clean up all external references and destroy the Animation State controller.- The
ParticleEmitter._frameLengthproperty is now specified on the class, rather than added dynamically at run-time, helping preserve class shape. - The
ParticleEmitter.defaultFrameproperty has been removed as it's not required. - Calling
ParticleEmitter.setFrameno longer resets the internal_frameCountervalue 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.configFastMapproperty has been moved to a local var within theParticleEmitterJS 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.configOpMapproperty has been moved to a local var within theParticleEmitterJS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory. Particle.sceneis a new property that references the Scene the Particle Emitter belongs to.Particle.animsis a new property that is an instance of theAnimationStatecomponent.Particle.emitis 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.isCroppedis a new read-only property. Do not modify.Particle.setSizeToFrameis a new internal NOOP method. Do not call.ParticleEmitter.animsis a new property that contains the Animation keys that can be assigned to Particles.ParticleEmitter.currentAnimis a new property that contains the index of the current animation, as tracked in cycle playback.ParticleEmitter.randomAnimis a new boolean property that controls if the animations are selected randomly, or in a cycle.ParticleEmitter.animQuantityis a new property that controls the number of consecutive particles that are emitted with the current animation.ParticleEmitter.countersis a new internal Float32Array that holds all the counters the Emitter uses.ParticleEmitter.getAnimis a new method, called by Particles when they are emitted, that will return the animation to use, if any.ParticleEmitter.setAnimis a new method, called with the Emitter Manager, that sets the animation data into the Emitter.- The
Particles.EmitterOp.toJSONmethod will now JSON stringify the property value before returning it. Particles.EmitterOp.methodis a new property that holds the current operation method being used. This is a read-only numeric value.Particles.EmitterOp.activeis 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.getMethodis a new internal method that returns the operation function being used as a numeric value. This is then cached in themethodproperty.- The
Particles.EmitterOp.setMethodsmethod 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.onChangemethod will now use the cached 'method' property to avoid running through thesetMethodsfunction 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.setConfigis a new method that allows you to set the configuration of the Emitter. Previously this was known asfromJSON.- The
ParticleEmitter.setPositionmethod no longer changes the position of the particle emission point, but of the Emitter itself. - The
ParticleEmitter.setBoundsmethod has been renamed tosetParticleBounds. - The
ParticleEmitter.setSpeedmethod has been renamed tosetParticleSpeed. - The
ParticleEmitter.setScalemethod has been renamed tosetParticleScaleassetScalewill now set the scale of the whole Emitter. - The
ParticleEmitter.setScaleXandsetScaleYmethods have been removed. Please usesetParticleScale. - The
ParticleEmitter.setGravitymethod has been renamed tosetParticleGravity. - The
ParticleEmitter.setGravityXandsetGravityYmethods have been removed. Please usesetParticleGravity. - The
ParticleEmitter.setAlphamethod has been renamed tosetParticleAlphaassetAlphawill now set the alpha of the whole Emitter. - The
ParticleEmitter.setTintmethod has been renamed tosetParticleTint. - The
ParticleEmitter.setLifespanmethod has been renamed tosetParticleLifespan. - The
ParticleEmitter.onproperty has been renamed toemittingto avoid conflicts with the Event Emitter. - The
ParticleEmitter.xproperty has been renamed toparticleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.yproperty has been renamed toparticleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleXproperty has been renamed toparticleScaleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleYproperty has been renamed toparticleScaleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.tintproperty has been renamed toparticleTintand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.alphaproperty has been renamed toparticleAlphaand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.angleproperty has been renamed toparticleAngleand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.rotateproperty has been renamed toparticleRotateand 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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
RenderTargetclass 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.clearandrebindit 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
mipmapFilterproperty 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 addmipmapFilter: '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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod is now passed the default pipeline and auto mobile setting from the Game Config.
Multi Tint Pipeline
- The
batchLinemethod 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.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
outTintEffectattribute 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. This should give most developers the same level of sequencing they had using Timelines, without the timing issues. - The
Tween.seekmethod 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 newseekmethod 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.originis now (0.5, 0.5) by default instead of (0, 0).The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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:
PostPipelineis a new Game Object Component that is now inherited by all Game Objects that are capable of using it.- Game Objects with the
PostPipelinecomponent now have a new property calledpostPipelineData. This object is used for storing Post Pipeline specific data in. Previously, both regular and post pipelines used the samepipelineDataobject, but this has now been split up for flexibility. - The
Pipeline.resetPipelinemethod no longer has its firstresetPostPipelinesargument. It now has just one argumentresetDataso please be aware of this if you call this function anywhere in your code. PostPipeline.initPostPipelineis a new method that should be called by any Game Object that supports Post Pipelines.- The following Game Objects now have the new
PostPipelineComponent exclusively:ContainerandLayer.
Input System Updates
There are breaking changes from previous versions of Phaser.
- The
InteractiveObject.alwaysEnabledproperty has been removed. It is no longer checked within theInputPluginand 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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow hands over most control of the framebuffers to the WebGLRenderer. - The
GameObjects.Components.Mask.createBitmapMaskmethod can now accept thex,y,textureandframeparameters new to the BitmapMask constructor. - Previously, calling
createBitmapMaskon 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
- The Arcade Physics World has a new property
tileFilterOptionswhich is an object passed to theGetTilesWithinmethods 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.strokeRoundedRectandfillRoundedRectmethods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow) AnimationManager.getAnimsFromTextureis 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.setLineSpacingis 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 alsoBitmapText.lineSpacingfor the property rather than the method.WebGLPipeline.vertexAvailableis a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.- The
TilemapandTilemapLayerclasses have a new methodgetTileCorners. 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.getAllPlayingis a new method that will return all currently playing sounds in the Sound Manager.Animation.showBeforeDelayis 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.resetPointersis 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.resetis a new method that will reset a Pointer instance back to its 'factory' settings.- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.Game.isPausedis a new boolean that tracks if the Game loop is paused, or not (and can also be toggled directly)ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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.getCentermethod now has an optionalincludeParentargument, which allows you to get the value in world space. - The
MatterTileBodyclass, which is created when you convert a Tilemap into a Matter Physics world, will now check to see if the Tile hasflipXorflipYset on it and rotate the body accordingly. Fix #5893 (thanks @Olliebrown @phaserhelp) - The
BaseCamerahas had itsAlphacomponent replaced withAlphaSingle. Previously you had access to properties such asalphaTopLeftthat never worked, now it correctly has just a single alpha property (thanks @samme) Time.Clock.startTimeis 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._matrixand_dataare now Float32Arrays.- Calling the
ColorMatrix.set,resetandgetDatamethods all now use the built-in Float32 Array operations, making them considerably faster. ColorMatrix.BLACK_WHITEis a new constant used by blackwhite operations.ColorMatrix.NEGATIVEis a new constant used by negative operations.ColorMatrix.DESATURATE_LUMINANCEis a new constant used by desaturation operations.ColorMatrix.SEPIAis a new constant used by sepia operations.ColorMatrix.LSDis a new constant used by LSD operations.ColorMatrix.BROWNis a new constant used by brown operations.ColorMatrix.VINTAGEis a new constant used by vintage pinhole operations.ColorMatrix.KODACHROMEis a new constant used by kodachrome operations.ColorMatrix.TECHNICOLORis a new constant used by technicolor operations.ColorMatrix.POLAROIDis a new constant used by polaroid operations.ColorMatrix.SHIFT_BGRis 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.haswill now return a strict boolean, rather than an object that can be cooerced into a boolean (thanks @samme)- The
CanvasTexture.drawmethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
CanvasTexture.drawFramemethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
CanvasTexture.clearmethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
Game.registry, which is aDataManagerinstance 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
GenerateVertsfunction has a new optional parameterflipUVwhich, if set, will flip the UV texture coordinates (thanks cedarcantab) - The
GenerateVertsfunction no longer errors if the verts and uvs arrays are not the same size andcontainsZis true (thanks cedarcantab) - The
Device.Browserchecks 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.processQueuemethod will no longerreturnif 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.scrollXandscrollYwill now only set theCamera.dirtyflag totrueif 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.updateis a new method that updates each of the Face vertices. This is now called internally byFace.isInView.Vertex.resizeis a new method that will set the position and then translate the Vertex based on an identity matrix.- The
Vertex.updatemethod now returnsthisto allow it to be chained. - You can now optionally specify the
maxSpeedvalue in the Arcade Physics Group config (thanks @samme) - You can now optionally specify the
useDampingboolean in the Arcade Physics Group config (thanks @samme) - Removed the
HexagonalTileToWorldYfunction as it cannot work without an X coordinate. UseHexagonalTileToWorldXYinstead. - Removed the
HexagonalWorldToTileYfunction as it cannot work without an X coordinate. UseHexagonalWorldToTileXYinstead. - 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.getAllmethod used to require akeyparameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned. - The
WebAudioSoundManagerwill 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_RESTOREDGame Event has been removed and the WebGL Renderer no longer listens for thecontextrestoredDOM event, or has acontextRestoredHandlermethod. 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
TextandTileSpriteGame Objects no longer listen for theCONTEXT_RESTOREDevent and have had theironContextRestoredmethods removed. Scenes.Systems.canInputis a new internal method that determines if a Scene can receive Input events, or not. This is now used by theInputPlugininstead of the previousisActivetest. This allows a Scene to emit and handle input events even when it is runninginitorpreload. Previously, it could only do this aftercreatehad finished running. Fix #6123 (thanks @yaasinhamidi)- The
BitmapTextGame Object has two new read-only propertiesdisplayWidthanddisplayHeight. This allows the BitmapText to correctly use theGetBoundscomponent. - The
BitmapTextGame Object now has theGetBoundscomponent added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames) WebGLSnapshotwill 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.snapshotFramebufferand 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 methodsnapshotAreahas had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)Animation.stopis always called when a new animation is loaded, regardless if the animation was playing or not and thedelayCounteris reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)ScaleManager.listenershas been renamed todomlistenersto avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)Geom.Intersects.LineToLinewill no longer create an internalPointobject, as it's not required internally (thanks @Trissolo)- The
tempZoneused byGridAlignhas now hadsetOrigin(0, 0)applied to it. This leads to more accurate / expected zone placement when aligning grid items. - The
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- The
TilemapLayer.skipCullfeature wasn't being applied correctly for Isometric, Hexagonal or Staggered tiles, only for Orthographic tiles (the default). It will now respect theskipCullproperty and return all tiles during culling if enabled. Fix #5524 (thanks @veleek) - Shutting down a Scene that didn't have the
LoaderPluginwould throw an error when removing event handlers. It now checks first, before removing (thanks @samme) - The
Container.getBoundsmethod will now usegetTextBoundsif one of its children is aBitmapTextGame Object, giving more accurate bounds results (thanks @EmilSV) - The
renderFlagsproperty, used to determine if a Game Object will render, or not, would be calculated incorrectly depending on the order of thescaleXandscaleYproperties. It now works regardless of the order (thanks @mizunokazumi) - The
SpriteSheetFromAtlasparser was using the incorrectsourceIndexto 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
maxSpeedsetting 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.jsentry 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_UPDATEevent from firing after the transition is over. Fix #5550 (thanks @mijinc0 @samme) - Although not recommended, when adding a
LayerGame Object to anotherLayerGame Object, it will no longer error because it cannot find theremoveFromDisplayListfunction. Fix #5595 (thanks @tringcooler) - The
Actions.Spreadmethod will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV) - Calling
setDisplayOriginon aVideoGame Object would cause the origins to be set toNaNif 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
ImageFileloads 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
dataKeyto specify a part of a JSON file when usingload.packwould 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.advancedWordWrapfunction 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
HexagonalTileToWorldXYfunction as it was incorrect. Now returns world coordinates correctly. Tilemap.copywould 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.copywill now use theDeepCopyfunction to copy theTile.propertiesobject, as otherwise it just gets copied by reference.- Recoded the point conversion math in the
HexagonalWorldToTileXYfunction as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich) - Fixed the point conversion math in the
IsometricWorldToTileXYfunction 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.worldToTileXorworldToTileYon a Isometric or Hexagonal Tilemap will now always returnnullinstead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should useworldToTileXYinstead. - The
Game.headlessStepmethod will now resetSceneManager.isProcessingbeforePRE_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.setPointswas called with the exact same number of points as before, it wouldn't set thedirtyflag, meaning the vertices were not updated on the next render (thanks @stupot) Particle.firewill 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)
TextGame 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.destroyLayermethod would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme) MapDataandObjectLayerwill now enforce that theTilemap.objectsproperty 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
ParseJSONTiledfunction will now run aDeepCopyon 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.setFromHSVwould not change the membersh,sandv, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow) - When calling
GameObject.getPostPipelineand 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
nextAnimproperty could get set toundefinedwhich 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.clearit will now callremoveDebugon the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton) - The
Video.loadURLmethod wouldn't load the video or emit theVIDEO_CREATEDevent unlessnoAudiowas specified. A load event handler has been added to resolve this (thanks @samme) - If you create a repeating or looping
TimerEventwith adelayof zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan) - The
endFrameandstartFrameproperties of theSpriteSheetparser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the givenstartFrameso that is frame zero and end atendFrame, regardless how many other frames are in the sheet. - Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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,lsdand 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.addGlowadds a Glow Pre FX effect to the Game Object.GameObject.preFX.addShadowadds a Shadow Pre FX effect to the Game Object.GameObject.preFX.addPixelateadds a Pixelate Pre FX effect to the Game Object.GameObject.preFX.addVignetteadds a Vignette Pre FX effect to the Game Object.GameObject.preFX.addShineadds a Shine Pre FX effect to the Game Object.GameObject.preFX.addBluradds a Blur Pre FX effect to the Game Object.GameObject.preFX.addGradientadds a Gradient Pre FX effect to the Game Object.GameObject.preFX.addBloomadds a Bloom Pre FX effect to the Game Object.GameObject.preFX.addColorMatrixadds a ColorMatrix Pre FX effect to the Game Object.GameObject.preFX.addCircleadds a Circle Pre FX effect to the Game Object.GameObject.preFX.addBarreladds a Barrel Pre FX effect to the Game Object.GameObject.preFX.addDisplacementadds a Displacement Pre FX effect to the Game Object.GameObject.preFX.addWipeadds a Wipe Pre FX effect to the Game Object.GameObject.preFX.addRevealadds a Reveal Pre FX effect to the Game Object.GameObject.preFX.addBokehadds a Bokeh Pre FX effect to the Game Object.GameObject.preFX.addTiltShiftadds a TiltShift Pre FX effect to the Game Object.
Available to all Game Objects:
GameObject.postFX.addGlowadds a Glow Post FX effect to the Game Object.GameObject.postFX.addShadowadds a Shadow Post FX effect to the Game Object.GameObject.postFX.addPixelateadds a Pixelate Post FX effect to the Game Object.GameObject.postFX.addVignetteadds a Vignette Post FX effect to the Game Object.GameObject.postFX.addShineadds a Shine Post FX effect to the Game Object.GameObject.postFX.addBluradds a Blur Post FX effect to the Game Object.GameObject.postFX.addGradientadds a Gradient Post FX effect to the Game Object.GameObject.postFX.addBloomadds a Bloom Post FX effect to the Game Object.GameObject.postFX.addColorMatrixadds a ColorMatrix Post FX effect to the Game Object.GameObject.postFX.addCircleadds a Circle Post FX effect to the Game Object.GameObject.postFX.addBarreladds a Barrel Post FX effect to the Game Object.GameObject.postFX.addDisplacementadds a Displacement Post FX effect to the Game Object.GameObject.postFX.addWipeadds a Wipe Post FX effect to the Game Object.GameObject.postFX.addRevealadds a Reveal Post FX effect to the Game Object.GameObject.postFX.addBokehadds a Bokeh Post FX effect to the Game Object.GameObject.postFX.addTiltShiftadds 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
drawDebugon 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
addandmakefunctions 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 (viaaddToScene: 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
SpineFileloader has now been updated so that the always-unique Spine key is pre-pended to the filename, for example if the key wasbonusand the PNG in the atlas wascoin.pngthen the final key (as stored in the Texture Manager) is nowbonus:coin.png. TheSpinePlugin.getAtlasCanvasandgetAtlasWebGLmethods have been updated to reflect this change. Fix #6022 (thanks @orjandh) - If a
SpineContainerhad 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isPreFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allPreFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Pre FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.- The
WebGLPipeline.setTimemethod has a new optional parametershader, which allows you to control the shader on which the time value is set. - If you add
#define SHADER_NAMEto the start of your shader then it will be picked up as theWebGLShadername during thesetShadersFromConfigprocess withinWebGLPipeline. - Calling
setPostPipelineon a Game Object will now pass thepipelineDataconfiguration object (if provided) to the pipeline instance being created. PipelineManager.getPostPipelinenow has an optional 3rd parameter, aconfigobject 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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
advanceproperty, or by calling the newParticleEmitter.fastForwardmethod. 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.startmethod has a new optional parameteradvancethat 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.durationis a new property that contains the duration that the Emitter will emit particles for in flow mode.- The
ParticleEmitter.startmethod has a new optional parameterduration, 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.stopmethod has a new optional parameterkill. 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
stopAfterproperty. This, combined with thefrequencyproperty 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
stopAftercounter is reset each time you call thestartorflowmethods.
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
holdconfiguration 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.STARTevent is fired whenever the Emitter begins emission of particles in flow mode. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.EXPLODEevent is fired whenever the Emitter explodes a bunch of particles via theexplodemethod. A reference to theParticleEmitterand a reference to the most recently firedParticleinstance are the two parameters. - The
Particles.Events.DEATH_ZONEevent is fired whenever a Particle is killed by a Death Zone. A reference to theParticleEmitter, the killedParticleand theDeathZonethat caused it are the 3 parameters. - The
Particles.Events.STOPevent is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call thestopmethod, or when an Emitter hits its duration or stopAfter limit. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.COMPLETEevent 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.addEmitZonemethod:
```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
totalproperty.EdgeZone.totalandRandomZone.totalare 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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeEmitZoneis a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getEmitZoneis a new method that Particles call when they are 'fired' in order to set their starting position, if any.- The property
ParticleEmitter.emitZonehas been removed. It has been replaced with the newParticleEmitter.emitZonesarray-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.addDeathZonemethod:
```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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeDeathZoneis a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getDeathZoneis 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.deathZonehas been removed. It has been replaced with the newParticleEmitter.deathZonesarray-based property.
Particle Colors
- You can now specify a new
colorproperty 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
colorEaseconfiguration 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 assine.outorquad.in, etc. If left undefined it will uselinearas default. EmitterColorOpis a brand new Emitter Op class that specifically controls the handling of color values, it extendsEmitterOpand uses the same methods but configured for faster color interpolation.- If you define
colorin your config it will override any Emitter tint values you may have set. In short, usecolorif you wish to adjust the color of the particles during their lifespan and usetintif you wish to modify either the entire emitter at once, or the color of the particles on birth only. ParticleEmitter.particleColoris a new property that allows you to get and set the particle color op value.ParticleEmitter.colorEaseis 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.sortPropertyandsortOrderAscproperties to set how (and if) particles should be sorted prior to rendering. For example, settingsortPropertytoywould 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.setSortPropertymethod allows you to modify the sort property and order at run-time. - The new
ParticleEmitter.setSortCallbackmethod 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.getBoundsmethod to return the bounds, which also gets stored in the newParticle.boundsRectangle property. ParticleEmitter.getBoundsis 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.viewBoundsis 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 newgetBoundsmethod to help define theviewBoundsarea.ParticleEmitter.overlapis 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.killis 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.getWorldTransformMatrixis a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.ParticleEmitter.worldMatrixis a new property that holds a TransformMatrix used for bounds calculations.
Particle Emitter Bounds
- Prior to v3.60 a Particle Emitter had a
boundsproperty. This was a Rectangle and if a Particle hit any of its edges it would rebound off it based on the Particlesbouncevalue. In v3.60 this action has been moved to a Particle Processor. You can still configure the bounds via the Emitter config using theboundsproperty, as before. And you can configure which faces collide via thecollideLeftetc properties. However, the following internal changes have taken place: ParticleBoundsis a new Particle Processor class that handles updating the particles.- The
ParticleEmitter.setBoundsmethod has been replaced withParticleEmitter.addParticleBoundswhich now returns a newParticleBoundsParticle Processor instance. - The
ParticleEmitter.boundsproperty has been removed. Please see theaddParticleBoundsmethod if you wish to retain this object. - The
ParticleEmitter.collideLeftproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideRightproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideTopproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideBottomproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
Particle.checkBoundsmethod has been removed as it's now handled by the Particle Processors.
Particle Processors
ParticleProcessoris 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.GravityWellnow extends the newParticleProcessorclass.ParticleEmitter.addParticleProcessoris a new method that allows you to add a Particle Processor instance to the Emitter. The oldcreateGravityWellmethod now uses this.ParticleEmitter.removeParticleProcessoris a new method that will remove a Particle Processor from an Emitter.ParticleEmitter.processorsis a new List property that contains all of the Particle Processors belonging to the Emitter.- The
ParticleEmitter.wellsproperty has been removed. You should now use the newprocessorsproperty instead, they are functionally identical. ParticleProcessor.updateis the method that handles all of the particle manipulation. It now has a new 4th parametertthat 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 viaParticleEmitter.flowCounterParticleEmitter._frameCounter- Now available viaParticleEmitter.frameCounterEmitterOp._onEmitis a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyEmitmethod, to ensure that the Emittercurrentproperty remains current.EmitterOp._onUpdateis a new private reference to the update callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyUpdatemethod, to ensure that the Emittercurrentproperty remains current.EmitterOp.destroyis a new method that nulls all references. This is called automatically when aParticleEmitteris itself destroyed.
Further Particle System Updates and Fixes:
- The Particle
DeathZone.willKillmethod now takes aParticleinstance 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.resetPositionmethod has been renamed tosetPositionand it now takes optional x/y parameters. If not given, it performs the same task asresetPositiondid in earlier versions. - The
ParticleEmitterclass now has theAlphaSingleComponent. This allows you to callsetAlphaon 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
frequencywasn'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, thepreUpdateloop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles. - Calling
ParticleEmitter.startwouldn't reset the_frameCountervalue internally, meaning the new emission didn't restart from the first texture frame again. ParticleEmitter.countersis a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous_counterand_frameCounterproperties have been merged into this array, along with new ones required for new features.- The WebGL Renderer will now use the new
setQuadfeature 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.preDestroyis 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.destroyis a new method that will clean up all external references and destroy the Animation State controller.- The
ParticleEmitter._frameLengthproperty is now specified on the class, rather than added dynamically at run-time, helping preserve class shape. - The
ParticleEmitter.defaultFrameproperty has been removed as it's not required. - Calling
ParticleEmitter.setFrameno longer resets the internal_frameCountervalue 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.configFastMapproperty has been moved to a local var within theParticleEmitterJS 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.configOpMapproperty has been moved to a local var within theParticleEmitterJS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory. Particle.sceneis a new property that references the Scene the Particle Emitter belongs to.Particle.animsis a new property that is an instance of theAnimationStatecomponent.Particle.emitis 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.isCroppedis a new read-only property. Do not modify.Particle.setSizeToFrameis a new internal NOOP method. Do not call.ParticleEmitter.animsis a new property that contains the Animation keys that can be assigned to Particles.ParticleEmitter.currentAnimis a new property that contains the index of the current animation, as tracked in cycle playback.ParticleEmitter.randomAnimis a new boolean property that controls if the animations are selected randomly, or in a cycle.ParticleEmitter.animQuantityis a new property that controls the number of consecutive particles that are emitted with the current animation.ParticleEmitter.countersis a new internal Float32Array that holds all the counters the Emitter uses.ParticleEmitter.getAnimis a new method, called by Particles when they are emitted, that will return the animation to use, if any.ParticleEmitter.setAnimis a new method, called with the Emitter Manager, that sets the animation data into the Emitter.- The
Particles.EmitterOp.toJSONmethod will now JSON stringify the property value before returning it. Particles.EmitterOp.methodis a new property that holds the current operation method being used. This is a read-only numeric value.Particles.EmitterOp.activeis 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.getMethodis a new internal method that returns the operation function being used as a numeric value. This is then cached in themethodproperty.- The
Particles.EmitterOp.setMethodsmethod 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.onChangemethod will now use the cached 'method' property to avoid running through thesetMethodsfunction 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.setConfigis a new method that allows you to set the configuration of the Emitter. Previously this was known asfromJSON.- The
ParticleEmitter.setPositionmethod no longer changes the position of the particle emission point, but of the Emitter itself. - The
ParticleEmitter.setBoundsmethod has been renamed tosetParticleBounds. - The
ParticleEmitter.setSpeedmethod has been renamed tosetParticleSpeed. - The
ParticleEmitter.setScalemethod has been renamed tosetParticleScaleassetScalewill now set the scale of the whole Emitter. - The
ParticleEmitter.setScaleXandsetScaleYmethods have been removed. Please usesetParticleScale. - The
ParticleEmitter.setGravitymethod has been renamed tosetParticleGravity. - The
ParticleEmitter.setGravityXandsetGravityYmethods have been removed. Please usesetParticleGravity. - The
ParticleEmitter.setAlphamethod has been renamed tosetParticleAlphaassetAlphawill now set the alpha of the whole Emitter. - The
ParticleEmitter.setTintmethod has been renamed tosetParticleTint. - The
ParticleEmitter.setLifespanmethod has been renamed tosetParticleLifespan. - The
ParticleEmitter.onproperty has been renamed toemittingto avoid conflicts with the Event Emitter. - The
ParticleEmitter.xproperty has been renamed toparticleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.yproperty has been renamed toparticleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleXproperty has been renamed toparticleScaleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleYproperty has been renamed toparticleScaleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.tintproperty has been renamed toparticleTintand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.alphaproperty has been renamed toparticleAlphaand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.angleproperty has been renamed toparticleAngleand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.rotateproperty has been renamed toparticleRotateand 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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
RenderTargetclass 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.clearandrebindit 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
mipmapFilterproperty 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 addmipmapFilter: '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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod is now passed the default pipeline and auto mobile setting from the Game Config.
Multi Tint Pipeline
- The
batchLinemethod 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.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
outTintEffectattribute 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. This should give most developers the same level of sequencing they had using Timelines, without the timing issues. - The
Tween.seekmethod 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 newseekmethod 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.originis now (0.5, 0.5) by default instead of (0, 0).The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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:
PostPipelineis a new Game Object Component that is now inherited by all Game Objects that are capable of using it.- Game Objects with the
PostPipelinecomponent now have a new property calledpostPipelineData. This object is used for storing Post Pipeline specific data in. Previously, both regular and post pipelines used the samepipelineDataobject, but this has now been split up for flexibility. - The
Pipeline.resetPipelinemethod no longer has its firstresetPostPipelinesargument. It now has just one argumentresetDataso please be aware of this if you call this function anywhere in your code. PostPipeline.initPostPipelineis a new method that should be called by any Game Object that supports Post Pipelines.- The following Game Objects now have the new
PostPipelineComponent exclusively:ContainerandLayer.
Input System Updates
There are breaking changes from previous versions of Phaser.
- The
InteractiveObject.alwaysEnabledproperty has been removed. It is no longer checked within theInputPluginand 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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow hands over most control of the framebuffers to the WebGLRenderer. - The
GameObjects.Components.Mask.createBitmapMaskmethod can now accept thex,y,textureandframeparameters new to the BitmapMask constructor. - Previously, calling
createBitmapMaskon 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
- The
Graphics.strokeRoundedRectandfillRoundedRectmethods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow) AnimationManager.getAnimsFromTextureis 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.setLineSpacingis 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 alsoBitmapText.lineSpacingfor the property rather than the method.WebGLPipeline.vertexAvailableis a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.- The
TilemapandTilemapLayerclasses have a new methodgetTileCorners. 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.getAllPlayingis a new method that will return all currently playing sounds in the Sound Manager.Animation.showBeforeDelayis 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.resetPointersis 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.resetis a new method that will reset a Pointer instance back to its 'factory' settings.- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.Game.isPausedis a new boolean that tracks if the Game loop is paused, or not (and can also be toggled directly)ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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
BaseCamerahas had itsAlphacomponent replaced withAlphaSingle. Previously you had access to properties such asalphaTopLeftthat never worked, now it correctly has just a single alpha property (thanks @samme) Time.Clock.startTimeis 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._matrixand_dataare now Float32Arrays.- Calling the
ColorMatrix.set,resetandgetDatamethods all now use the built-in Float32 Array operations, making them considerably faster. ColorMatrix.BLACK_WHITEis a new constant used by blackwhite operations.ColorMatrix.NEGATIVEis a new constant used by negative operations.ColorMatrix.DESATURATE_LUMINANCEis a new constant used by desaturation operations.ColorMatrix.SEPIAis a new constant used by sepia operations.ColorMatrix.LSDis a new constant used by LSD operations.ColorMatrix.BROWNis a new constant used by brown operations.ColorMatrix.VINTAGEis a new constant used by vintage pinhole operations.ColorMatrix.KODACHROMEis a new constant used by kodachrome operations.ColorMatrix.TECHNICOLORis a new constant used by technicolor operations.ColorMatrix.POLAROIDis a new constant used by polaroid operations.ColorMatrix.SHIFT_BGRis 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.haswill now return a strict boolean, rather than an object that can be cooerced into a boolean (thanks @samme)- The
CanvasTexture.drawmethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
CanvasTexture.drawFramemethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
CanvasTexture.clearmethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
Game.registry, which is aDataManagerinstance 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
GenerateVertsfunction has a new optional parameterflipUVwhich, if set, will flip the UV texture coordinates (thanks cedarcantab) - The
GenerateVertsfunction no longer errors if the verts and uvs arrays are not the same size andcontainsZis true (thanks cedarcantab) - The
Device.Browserchecks 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.processQueuemethod will no longerreturnif 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.scrollXandscrollYwill now only set theCamera.dirtyflag totrueif 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.updateis a new method that updates each of the Face vertices. This is now called internally byFace.isInView.Vertex.resizeis a new method that will set the position and then translate the Vertex based on an identity matrix.- The
Vertex.updatemethod now returnsthisto allow it to be chained. - You can now optionally specify the
maxSpeedvalue in the Arcade Physics Group config (thanks @samme) - You can now optionally specify the
useDampingboolean in the Arcade Physics Group config (thanks @samme) - Removed the
HexagonalTileToWorldYfunction as it cannot work without an X coordinate. UseHexagonalTileToWorldXYinstead. - Removed the
HexagonalWorldToTileYfunction as it cannot work without an X coordinate. UseHexagonalWorldToTileXYinstead. - 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.getAllmethod used to require akeyparameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned. - The
WebAudioSoundManagerwill 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_RESTOREDGame Event has been removed and the WebGL Renderer no longer listens for thecontextrestoredDOM event, or has acontextRestoredHandlermethod. 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
TextandTileSpriteGame Objects no longer listen for theCONTEXT_RESTOREDevent and have had theironContextRestoredmethods removed. Scenes.Systems.canInputis a new internal method that determines if a Scene can receive Input events, or not. This is now used by theInputPlugininstead of the previousisActivetest. This allows a Scene to emit and handle input events even when it is runninginitorpreload. Previously, it could only do this aftercreatehad finished running. Fix #6123 (thanks @yaasinhamidi)- The
BitmapTextGame Object has two new read-only propertiesdisplayWidthanddisplayHeight. This allows the BitmapText to correctly use theGetBoundscomponent. - The
BitmapTextGame Object now has theGetBoundscomponent added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames) WebGLSnapshotwill 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.snapshotFramebufferand 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 methodsnapshotAreahas had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)Animation.stopis always called when a new animation is loaded, regardless if the animation was playing or not and thedelayCounteris reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)ScaleManager.listenershas been renamed todomlistenersto avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)Geom.Intersects.LineToLinewill no longer create an internalPointobject, as it's not required internally (thanks @Trissolo)- The
tempZoneused byGridAlignhas now hadsetOrigin(0, 0)applied to it. This leads to more accurate / expected zone placement when aligning grid items. - The
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- The
Container.getBoundsmethod will now usegetTextBoundsif one of its children is aBitmapTextGame Object, giving more accurate bounds results (thanks @EmilSV) - The
renderFlagsproperty, used to determine if a Game Object will render, or not, would be calculated incorrectly depending on the order of thescaleXandscaleYproperties. It now works regardless of the order (thanks @mizunokazumi) - The
SpriteSheetFromAtlasparser was using the incorrectsourceIndexto 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
maxSpeedsetting 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.jsentry 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_UPDATEevent from firing after the transition is over. Fix #5550 (thanks @mijinc0 @samme) - Although not recommended, when adding a
LayerGame Object to anotherLayerGame Object, it will no longer error because it cannot find theremoveFromDisplayListfunction. Fix #5595 (thanks @tringcooler) - The
Actions.Spreadmethod will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV) - Calling
setDisplayOriginon aVideoGame Object would cause the origins to be set toNaNif 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
ImageFileloads 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
dataKeyto specify a part of a JSON file when usingload.packwould 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.advancedWordWrapfunction 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
HexagonalTileToWorldXYfunction as it was incorrect. Now returns world coordinates correctly. Tilemap.copywould 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.copywill now use theDeepCopyfunction to copy theTile.propertiesobject, as otherwise it just gets copied by reference.- Recoded the point conversion math in the
HexagonalWorldToTileXYfunction as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich) - Fixed the point conversion math in the
IsometricWorldToTileXYfunction 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.worldToTileXorworldToTileYon a Isometric or Hexagonal Tilemap will now always returnnullinstead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should useworldToTileXYinstead. - The
Game.headlessStepmethod will now resetSceneManager.isProcessingbeforePRE_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.setPointswas called with the exact same number of points as before, it wouldn't set thedirtyflag, meaning the vertices were not updated on the next render (thanks @stupot) Particle.firewill 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)
TextGame 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.destroyLayermethod would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme) MapDataandObjectLayerwill now enforce that theTilemap.objectsproperty 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
ParseJSONTiledfunction will now run aDeepCopyon 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.setFromHSVwould not change the membersh,sandv, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow) - When calling
GameObject.getPostPipelineand 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
nextAnimproperty could get set toundefinedwhich 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.clearit will now callremoveDebugon the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton) - The
Video.loadURLmethod wouldn't load the video or emit theVIDEO_CREATEDevent unlessnoAudiowas specified. A load event handler has been added to resolve this (thanks @samme) - If you create a repeating or looping
TimerEventwith adelayof zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan) - The
endFrameandstartFrameproperties of theSpriteSheetparser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the givenstartFrameso that is frame zero and end atendFrame, regardless how many other frames are in the sheet. - Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent 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,lsdand 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.addGlowadds a Glow Pre FX effect to the Game Object.GameObject.preFX.addShadowadds a Shadow Pre FX effect to the Game Object.GameObject.preFX.addPixelateadds a Pixelate Pre FX effect to the Game Object.GameObject.preFX.addVignetteadds a Vignette Pre FX effect to the Game Object.GameObject.preFX.addShineadds a Shine Pre FX effect to the Game Object.GameObject.preFX.addBluradds a Blur Pre FX effect to the Game Object.GameObject.preFX.addGradientadds a Gradient Pre FX effect to the Game Object.GameObject.preFX.addBloomadds a Bloom Pre FX effect to the Game Object.GameObject.preFX.addColorMatrixadds a ColorMatrix Pre FX effect to the Game Object.GameObject.preFX.addCircleadds a Circle Pre FX effect to the Game Object.GameObject.preFX.addBarreladds a Barrel Pre FX effect to the Game Object.GameObject.preFX.addDisplacementadds a Displacement Pre FX effect to the Game Object.GameObject.preFX.addWipeadds a Wipe Pre FX effect to the Game Object.GameObject.preFX.addRevealadds a Reveal Pre FX effect to the Game Object.GameObject.preFX.addBokehadds a Bokeh Pre FX effect to the Game Object.GameObject.preFX.addTiltShiftadds a TiltShift Pre FX effect to the Game Object.
Available to all Game Objects:
GameObject.postFX.addGlowadds a Glow Post FX effect to the Game Object.GameObject.postFX.addShadowadds a Shadow Post FX effect to the Game Object.GameObject.postFX.addPixelateadds a Pixelate Post FX effect to the Game Object.GameObject.postFX.addVignetteadds a Vignette Post FX effect to the Game Object.GameObject.postFX.addShineadds a Shine Post FX effect to the Game Object.GameObject.postFX.addBluradds a Blur Post FX effect to the Game Object.GameObject.postFX.addGradientadds a Gradient Post FX effect to the Game Object.GameObject.postFX.addBloomadds a Bloom Post FX effect to the Game Object.GameObject.postFX.addColorMatrixadds a ColorMatrix Post FX effect to the Game Object.GameObject.postFX.addCircleadds a Circle Post FX effect to the Game Object.GameObject.postFX.addBarreladds a Barrel Post FX effect to the Game Object.GameObject.postFX.addDisplacementadds a Displacement Post FX effect to the Game Object.GameObject.postFX.addWipeadds a Wipe Post FX effect to the Game Object.GameObject.postFX.addRevealadds a Reveal Post FX effect to the Game Object.GameObject.postFX.addBokehadds a Bokeh Post FX effect to the Game Object.GameObject.postFX.addTiltShiftadds 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
drawDebugon 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
addandmakefunctions 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 (viaaddToScene: 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
SpineFileloader has now been updated so that the always-unique Spine key is pre-pended to the filename, for example if the key wasbonusand the PNG in the atlas wascoin.pngthen the final key (as stored in the Texture Manager) is nowbonus:coin.png. TheSpinePlugin.getAtlasCanvasandgetAtlasWebGLmethods have been updated to reflect this change. Fix #6022 (thanks @orjandh) - If a
SpineContainerhad 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isPreFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allPreFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Pre FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat matches the size of the main target. This is called by Pre FX pipelines and not typically called directly.- The
WebGLPipeline.setTimemethod has a new optional parametershader, which allows you to control the shader on which the time value is set. - If you add
#define SHADER_NAMEto the start of your shader then it will be picked up as theWebGLShadername during thesetShadersFromConfigprocess withinWebGLPipeline.
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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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
advanceproperty, or by calling the newParticleEmitter.fastForwardmethod. 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.startmethod has a new optional parameteradvancethat 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.durationis a new property that contains the duration that the Emitter will emit particles for in flow mode.- The
ParticleEmitter.startmethod has a new optional parameterduration, 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.stopmethod has a new optional parameterkill. 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
stopAfterproperty. This, combined with thefrequencyproperty 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
stopAftercounter is reset each time you call thestartorflowmethods.
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
holdconfiguration 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.STARTevent is fired whenever the Emitter begins emission of particles in flow mode. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.EXPLODEevent is fired whenever the Emitter explodes a bunch of particles via theexplodemethod. A reference to theParticleEmitterand a reference to the most recently firedParticleinstance are the two parameters. - The
Particles.Events.DEATH_ZONEevent is fired whenever a Particle is killed by a Death Zone. A reference to theParticleEmitter, the killedParticleand theDeathZonethat caused it are the 3 parameters. - The
Particles.Events.STOPevent is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call thestopmethod, or when an Emitter hits its duration or stopAfter limit. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.COMPLETEevent 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.addEmitZonemethod:
```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
totalproperty.EdgeZone.totalandRandomZone.totalare 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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeEmitZoneis a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getEmitZoneis a new method that Particles call when they are 'fired' in order to set their starting position, if any.- The property
ParticleEmitter.emitZonehas been removed. It has been replaced with the newParticleEmitter.emitZonesarray-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.addDeathZonemethod:
```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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeDeathZoneis a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getDeathZoneis 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.deathZonehas been removed. It has been replaced with the newParticleEmitter.deathZonesarray-based property.
Particle Colors
- You can now specify a new
colorproperty 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
colorEaseconfiguration 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 assine.outorquad.in, etc. If left undefined it will uselinearas default. EmitterColorOpis a brand new Emitter Op class that specifically controls the handling of color values, it extendsEmitterOpand uses the same methods but configured for faster color interpolation.- If you define
colorin your config it will override any Emitter tint values you may have set. In short, usecolorif you wish to adjust the color of the particles during their lifespan and usetintif you wish to modify either the entire emitter at once, or the color of the particles on birth only. ParticleEmitter.particleColoris a new property that allows you to get and set the particle color op value.ParticleEmitter.colorEaseis 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.sortPropertyandsortOrderAscproperties to set how (and if) particles should be sorted prior to rendering. For example, settingsortPropertytoywould 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.setSortPropertymethod allows you to modify the sort property and order at run-time. - The new
ParticleEmitter.setSortCallbackmethod 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.getBoundsmethod to return the bounds, which also gets stored in the newParticle.boundsRectangle property. ParticleEmitter.getBoundsis 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.viewBoundsis 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 newgetBoundsmethod to help define theviewBoundsarea.ParticleEmitter.overlapis 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.killis 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.getWorldTransformMatrixis a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.ParticleEmitter.worldMatrixis a new property that holds a TransformMatrix used for bounds calculations.
Particle Emitter Bounds
- Prior to v3.60 a Particle Emitter had a
boundsproperty. This was a Rectangle and if a Particle hit any of its edges it would rebound off it based on the Particlesbouncevalue. In v3.60 this action has been moved to a Particle Processor. You can still configure the bounds via the Emitter config using theboundsproperty, as before. And you can configure which faces collide via thecollideLeftetc properties. However, the following internal changes have taken place: ParticleBoundsis a new Particle Processor class that handles updating the particles.- The
ParticleEmitter.setBoundsmethod has been replaced withParticleEmitter.addParticleBoundswhich now returns a newParticleBoundsParticle Processor instance. - The
ParticleEmitter.boundsproperty has been removed. Please see theaddParticleBoundsmethod if you wish to retain this object. - The
ParticleEmitter.collideLeftproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideRightproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideTopproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
ParticleEmitter.collideBottomproperty has been removed. It's now part of theParticleBoundsParticle Processor. - The
Particle.checkBoundsmethod has been removed as it's now handled by the Particle Processors.
Particle Processors
ParticleProcessoris 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.GravityWellnow extends the newParticleProcessorclass.ParticleEmitter.addParticleProcessoris a new method that allows you to add a Particle Processor instance to the Emitter. The oldcreateGravityWellmethod now uses this.ParticleEmitter.removeParticleProcessoris a new method that will remove a Particle Processor from an Emitter.ParticleEmitter.processorsis a new List property that contains all of the Particle Processors belonging to the Emitter.- The
ParticleEmitter.wellsproperty has been removed. You should now use the newprocessorsproperty instead, they are functionally identical. ParticleProcessor.updateis the method that handles all of the particle manipulation. It now has a new 4th parametertthat 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 viaParticleEmitter.flowCounterParticleEmitter._frameCounter- Now available viaParticleEmitter.frameCounterEmitterOp._onEmitis a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyEmitmethod, to ensure that the Emittercurrentproperty remains current.EmitterOp._onUpdateis a new private reference to the update callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyUpdatemethod, to ensure that the Emittercurrentproperty remains current.EmitterOp.destroyis a new method that nulls all references. This is called automatically when aParticleEmitteris itself destroyed.
Further Particle System Updates and Fixes:
- The Particle
DeathZone.willKillmethod now takes aParticleinstance 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.resetPositionmethod has been renamed tosetPositionand it now takes optional x/y parameters. If not given, it performs the same task asresetPositiondid in earlier versions. - The
ParticleEmitterclass now has theAlphaSingleComponent. This allows you to callsetAlphaon 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
frequencywasn'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, thepreUpdateloop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles. - Calling
ParticleEmitter.startwouldn't reset the_frameCountervalue internally, meaning the new emission didn't restart from the first texture frame again. ParticleEmitter.countersis a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous_counterand_frameCounterproperties have been merged into this array, along with new ones required for new features.- The WebGL Renderer will now use the new
setQuadfeature 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.preDestroyis 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.destroyis a new method that will clean up all external references and destroy the Animation State controller.- The
ParticleEmitter._frameLengthproperty is now specified on the class, rather than added dynamically at run-time, helping preserve class shape. - The
ParticleEmitter.defaultFrameproperty has been removed as it's not required. - Calling
ParticleEmitter.setFrameno longer resets the internal_frameCountervalue 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.configFastMapproperty has been moved to a local var within theParticleEmitterJS 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.configOpMapproperty has been moved to a local var within theParticleEmitterJS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory. Particle.sceneis a new property that references the Scene the Particle Emitter belongs to.Particle.animsis a new property that is an instance of theAnimationStatecomponent.Particle.emitis 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.isCroppedis a new read-only property. Do not modify.Particle.setSizeToFrameis a new internal NOOP method. Do not call.ParticleEmitter.animsis a new property that contains the Animation keys that can be assigned to Particles.ParticleEmitter.currentAnimis a new property that contains the index of the current animation, as tracked in cycle playback.ParticleEmitter.randomAnimis a new boolean property that controls if the animations are selected randomly, or in a cycle.ParticleEmitter.animQuantityis a new property that controls the number of consecutive particles that are emitted with the current animation.ParticleEmitter.countersis a new internal Float32Array that holds all the counters the Emitter uses.ParticleEmitter.getAnimis a new method, called by Particles when they are emitted, that will return the animation to use, if any.ParticleEmitter.setAnimis a new method, called with the Emitter Manager, that sets the animation data into the Emitter.- The
Particles.EmitterOp.toJSONmethod will now JSON stringify the property value before returning it. Particles.EmitterOp.methodis a new property that holds the current operation method being used. This is a read-only numeric value.Particles.EmitterOp.activeis 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.getMethodis a new internal method that returns the operation function being used as a numeric value. This is then cached in themethodproperty.- The
Particles.EmitterOp.setMethodsmethod 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.onChangemethod will now use the cached 'method' property to avoid running through thesetMethodsfunction 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.setConfigis a new method that allows you to set the configuration of the Emitter. Previously this was known asfromJSON.- The
ParticleEmitter.setPositionmethod no longer changes the position of the particle emission point, but of the Emitter itself. - The
ParticleEmitter.setBoundsmethod has been renamed tosetParticleBounds. - The
ParticleEmitter.setSpeedmethod has been renamed tosetParticleSpeed. - The
ParticleEmitter.setScalemethod has been renamed tosetParticleScaleassetScalewill now set the scale of the whole Emitter. - The
ParticleEmitter.setScaleXandsetScaleYmethods have been removed. Please usesetParticleScale. - The
ParticleEmitter.setGravitymethod has been renamed tosetParticleGravity. - The
ParticleEmitter.setGravityXandsetGravityYmethods have been removed. Please usesetParticleGravity. - The
ParticleEmitter.setAlphamethod has been renamed tosetParticleAlphaassetAlphawill now set the alpha of the whole Emitter. - The
ParticleEmitter.setTintmethod has been renamed tosetParticleTint. - The
ParticleEmitter.setLifespanmethod has been renamed tosetParticleLifespan. - The
ParticleEmitter.onproperty has been renamed toemittingto avoid conflicts with the Event Emitter. - The
ParticleEmitter.xproperty has been renamed toparticleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.yproperty has been renamed toparticleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleXproperty has been renamed toparticleScaleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleYproperty has been renamed toparticleScaleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.tintproperty has been renamed toparticleTintand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.alphaproperty has been renamed toparticleAlphaand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.angleproperty has been renamed toparticleAngleand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.rotateproperty has been renamed toparticleRotateand 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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
RenderTargetclass 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.clearandrebindit 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
mipmapFilterproperty 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 addmipmapFilter: '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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod is now passed the default pipeline and auto mobile setting from the Game Config.
Multi Tint Pipeline
- The
batchLinemethod 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.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
outTintEffectattribute 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. This should give most developers the same level of sequencing they had using Timelines, without the timing issues. - The
Tween.seekmethod 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 newseekmethod 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.originis now (0.5, 0.5) by default instead of (0, 0).The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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:
PostPipelineis a new Game Object Component that is now inherited by all Game Objects that are capable of using it.- Game Objects with the
PostPipelinecomponent now have a new property calledpostPipelineData. This object is used for storing Post Pipeline specific data in. Previously, both regular and post pipelines used the samepipelineDataobject, but this has now been split up for flexibility. - The
Pipeline.resetPipelinemethod no longer has its firstresetPostPipelinesargument. It now has just one argumentresetDataso please be aware of this if you call this function anywhere in your code. PostPipeline.initPostPipelineis a new method that should be called by any Game Object that supports Post Pipelines.- The following Game Objects now have the new
PostPipelineComponent exclusively:ContainerandLayer.
Input System Updates
There are breaking changes from previous versions of Phaser.
- The
InteractiveObject.alwaysEnabledproperty has been removed. It is no longer checked within theInputPluginand 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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow hands over most control of the framebuffers to the WebGLRenderer. - The
GameObjects.Components.Mask.createBitmapMaskmethod can now accept thex,y,textureandframeparameters new to the BitmapMask constructor. - Previously, calling
createBitmapMaskon 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
- The
Graphics.strokeRoundedRectandfillRoundedRectmethods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow) AnimationManager.getAnimsFromTextureis 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.setLineSpacingis 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 alsoBitmapText.lineSpacingfor the property rather than the method.WebGLPipeline.vertexAvailableis a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.- The
TilemapandTilemapLayerclasses have a new methodgetTileCorners. 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.getAllPlayingis a new method that will return all currently playing sounds in the Sound Manager.Animation.showBeforeDelayis 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.resetPointersis 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.resetis a new method that will reset a Pointer instance back to its 'factory' settings.- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.Game.isPausedis a new boolean that tracks if the Game loop is paused, or not (and can also be toggled directly)ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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
BaseCamerahas had itsAlphacomponent replaced withAlphaSingle. Previously you had access to properties such asalphaTopLeftthat never worked, now it correctly has just a single alpha property (thanks @samme) Time.Clock.startTimeis 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._matrixand_dataare now Float32Arrays.- Calling the
ColorMatrix.set,resetandgetDatamethods all now use the built-in Float32 Array operations, making them considerably faster. ColorMatrix.BLACK_WHITEis a new constant used by blackwhite operations.ColorMatrix.NEGATIVEis a new constant used by negative operations.ColorMatrix.DESATURATE_LUMINANCEis a new constant used by desaturation operations.ColorMatrix.SEPIAis a new constant used by sepia operations.ColorMatrix.LSDis a new constant used by LSD operations.ColorMatrix.BROWNis a new constant used by brown operations.ColorMatrix.VINTAGEis a new constant used by vintage pinhole operations.ColorMatrix.KODACHROMEis a new constant used by kodachrome operations.ColorMatrix.TECHNICOLORis a new constant used by technicolor operations.ColorMatrix.POLAROIDis a new constant used by polaroid operations.ColorMatrix.SHIFT_BGRis 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.haswill now return a strict boolean, rather than an object that can be cooerced into a boolean (thanks @samme)- The
CanvasTexture.drawmethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
CanvasTexture.drawFramemethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
CanvasTexture.clearmethod has a new optional parameterupdatewhich allows you to control if the internal ImageData is recalculated, or not (thanks @samme) - The
Game.registry, which is aDataManagerinstance 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
GenerateVertsfunction has a new optional parameterflipUVwhich, if set, will flip the UV texture coordinates (thanks cedarcantab) - The
GenerateVertsfunction no longer errors if the verts and uvs arrays are not the same size andcontainsZis true (thanks cedarcantab) - The
Device.Browserchecks 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.processQueuemethod will no longerreturnif 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.scrollXandscrollYwill now only set theCamera.dirtyflag totrueif 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.updateis a new method that updates each of the Face vertices. This is now called internally byFace.isInView.Vertex.resizeis a new method that will set the position and then translate the Vertex based on an identity matrix.- The
Vertex.updatemethod now returnsthisto allow it to be chained. - You can now optionally specify the
maxSpeedvalue in the Arcade Physics Group config (thanks @samme) - You can now optionally specify the
useDampingboolean in the Arcade Physics Group config (thanks @samme) - Removed the
HexagonalTileToWorldYfunction as it cannot work without an X coordinate. UseHexagonalTileToWorldXYinstead. - Removed the
HexagonalWorldToTileYfunction as it cannot work without an X coordinate. UseHexagonalWorldToTileXYinstead. - 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.getAllmethod used to require akeyparameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned. - The
WebAudioSoundManagerwill 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_RESTOREDGame Event has been removed and the WebGL Renderer no longer listens for thecontextrestoredDOM event, or has acontextRestoredHandlermethod. 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
TextandTileSpriteGame Objects no longer listen for theCONTEXT_RESTOREDevent and have had theironContextRestoredmethods removed. Scenes.Systems.canInputis a new internal method that determines if a Scene can receive Input events, or not. This is now used by theInputPlugininstead of the previousisActivetest. This allows a Scene to emit and handle input events even when it is runninginitorpreload. Previously, it could only do this aftercreatehad finished running. Fix #6123 (thanks @yaasinhamidi)- The
BitmapTextGame Object has two new read-only propertiesdisplayWidthanddisplayHeight. This allows the BitmapText to correctly use theGetBoundscomponent. - The
BitmapTextGame Object now has theGetBoundscomponent added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames) WebGLSnapshotwill 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.snapshotFramebufferand 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 methodsnapshotAreahas had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)Animation.stopis always called when a new animation is loaded, regardless if the animation was playing or not and thedelayCounteris reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)ScaleManager.listenershas been renamed todomlistenersto avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)Geom.Intersects.LineToLinewill no longer create an internalPointobject, as it's not required internally (thanks @Trissolo)- The
tempZoneused byGridAlignhas now hadsetOrigin(0, 0)applied to it. This leads to more accurate / expected zone placement when aligning grid items. - The
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- The
Container.getBoundsmethod will now usegetTextBoundsif one of its children is aBitmapTextGame Object, giving more accurate bounds results (thanks @EmilSV) - The
renderFlagsproperty, used to determine if a Game Object will render, or not, would be calculated incorrectly depending on the order of thescaleXandscaleYproperties. It now works regardless of the order (thanks @mizunokazumi) - The
SpriteSheetFromAtlasparser was using the incorrectsourceIndexto 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
maxSpeedsetting 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.jsentry 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_UPDATEevent from firing after the transition is over. Fix #5550 (thanks @mijinc0 @samme) - Although not recommended, when adding a
LayerGame Object to anotherLayerGame Object, it will no longer error because it cannot find theremoveFromDisplayListfunction. Fix #5595 (thanks @tringcooler) - The
Actions.Spreadmethod will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV) - Calling
setDisplayOriginon aVideoGame Object would cause the origins to be set toNaNif 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
ImageFileloads 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
dataKeyto specify a part of a JSON file when usingload.packwould 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.advancedWordWrapfunction 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
HexagonalTileToWorldXYfunction as it was incorrect. Now returns world coordinates correctly. Tilemap.copywould 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.copywill now use theDeepCopyfunction to copy theTile.propertiesobject, as otherwise it just gets copied by reference.- Recoded the point conversion math in the
HexagonalWorldToTileXYfunction as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich) - Fixed the point conversion math in the
IsometricWorldToTileXYfunction 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.worldToTileXorworldToTileYon a Isometric or Hexagonal Tilemap will now always returnnullinstead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should useworldToTileXYinstead. - The
Game.headlessStepmethod will now resetSceneManager.isProcessingbeforePRE_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.setPointswas called with the exact same number of points as before, it wouldn't set thedirtyflag, meaning the vertices were not updated on the next render (thanks @stupot) Particle.firewill 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)
TextGame 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.destroyLayermethod would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme) MapDataandObjectLayerwill now enforce that theTilemap.objectsproperty 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
ParseJSONTiledfunction will now run aDeepCopyon 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.setFromHSVwould not change the membersh,sandv, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow) - When calling
GameObject.getPostPipelineand 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
nextAnimproperty could get set toundefinedwhich 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.clearit will now callremoveDebugon the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton) - The
Video.loadURLmethod wouldn't load the video or emit theVIDEO_CREATEDevent unlessnoAudiowas specified. A load event handler has been added to resolve this (thanks @samme) - If you create a repeating or looping
TimerEventwith adelayof zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan) - The
endFrameandstartFrameproperties of theSpriteSheetparser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the givenstartFrameso that is frame zero and end atendFrame, regardless how many other frames are in the sheet. - Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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
advanceproperty, or by calling the newParticleEmitter.fastForwardmethod. 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.startmethod has a new optional parameteradvancethat 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.durationis a new property that contains the duration that the Emitter will emit particles for in flow mode.- The
ParticleEmitter.startmethod has a new optional parameterduration, 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.stopmethod has a new optional parameterkill. 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
stopAfterproperty. This, combined with thefrequencyproperty 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
stopAftercounter is reset each time you call thestartorflowmethods.
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.STARTevent is fired whenever the Emitter begins emission of particles in flow mode. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.EXPLODEevent is fired whenever the Emitter explodes a bunch of particles via theexplodemethod. A reference to theParticleEmitterand a reference to the most recently firedParticleinstance are the two parameters. - The
Particles.Events.DEATH_ZONEevent is fired whenever a Particle is killed by a Death Zone. A reference to theParticleEmitter, the killedParticleand theDeathZonethat caused it are the 3 parameters. - The
Particles.Events.STOPevent is fired whenever the Emitter finishes emission of particles in flow mode. This happens either when you call thestopmethod, or when an Emitter hits its duration or stopAfter limit. A reference to theParticleEmitteris included as the only parameter. - The
Particles.Events.COMPLETEevent 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.addEmitZonemethod:
```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
totalproperty.EdgeZone.totalandRandomZone.totalare 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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeEmitZoneis a new method that allows you to remove an Emit Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getEmitZoneis a new method that Particles call when they are 'fired' in order to set their starting position, if any.- The property
ParticleEmitter.emitZonehas been removed. It has been replaced with the newParticleEmitter.emitZonesarray-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.addDeathZonemethod:
```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
setEmitZonenow performs a different task than before. It's now an alias foraddEmitZone. 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#removeDeathZoneis a new method that allows you to remove a Death Zone from an Emitter without needing to modify the internal zones array.ParticleEmitter.getDeathZoneis 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.deathZonehas been removed. It has been replaced with the newParticleEmitter.deathZonesarray-based property.
Particle Colors
- You can now specify a new
colorproperty 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
colorEaseconfiguration 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 assine.outorquad.in, etc. If left undefined it will uselinearas default. EmitterColorOpis a brand new Emitter Op class that specifically controls the handling of color values, it extendsEmitterOpand uses the same methods but configured for faster color interpolation.- If you define
colorin your config it will override any Emitter tint values you may have set. In short, usecolorif you wish to adjust the color of the particles during their lifespan and usetintif you wish to modify either the entire emitter at once, or the color of the particles on birth only. ParticleEmitter.particleColoris a new property that allows you to get and set the particle color op value.ParticleEmitter.colorEaseis 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.sortPropertyandsortOrderAscproperties to set how (and if) particles should be sorted prior to rendering. For example, settingsortPropertytoywould 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.setSortPropertymethod allows you to modify the sort property and order at run-time. - The new
ParticleEmitter.setSortCallbackmethod 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.getBoundsmethod to return the bounds, which also gets stored in the newParticle.boundsRectangle property. ParticleEmitter.getBoundsis 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.viewBoundsis 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 newgetBoundsmethod to help define theviewBoundsarea.ParticleEmitter.overlapis 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.killis 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.getWorldTransformMatrixis a new method that allows a Particle Emitter to calculate its world transform, factoring in any parents.ParticleEmitter.worldMatrixis a new property that holds a TransformMatrix used for bounds calculations.
Particle Processors
ParticleProcessoris 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.GravityWellnow extends the newParticleProcessorclass.ParticleEmitter.addParticleProcessoris a new method that allows you to add a Particle Processor instance to the Emitter. The oldcreateGravityWellmethod now uses this.ParticleEmitter.removeParticleProcessoris a new method that will remove a Particle Processor from an Emitter.ParticleEmitter.processorsis a new List property that contains all of the Particle Processors belonging to the Emitter.- The
ParticleEmitter.wellsproperty has been removed. You should now use the newprocessorsproperty instead, they are functionally identical. ParticleProcessor.updateis the method that handles all of the particle manipulation. It now has a new 4th parametertthat 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 viaParticleEmitter.flowCounterParticleEmitter._frameCounter- Now available viaParticleEmitter.frameCounterEmitterOp._onEmitis a new private reference to the emit callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyEmitmethod, to ensure that the Emittercurrentproperty remains current.EmitterOp._onUpdateis a new private reference to the update callback function, if specified in the emitter configuration. It is called by the newEmitterOp.proxyUpdatemethod, to ensure that the Emittercurrentproperty remains current.EmitterOp.destroyis a new method that nulls all references. This is called automatically when aParticleEmitteris itself destroyed.
Further Particle System Updates and Fixes:
- The
Particle.resetPositionmethod has been renamed tosetPositionand it now takes optional x/y parameters. If not given, it performs the same task asresetPositiondid in earlier versions. - The
ParticleEmitterclass now has theAlphaSingleComponent. This allows you to callsetAlphaon 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
frequencywasn'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, thepreUpdateloop was calculating the value incorrectly. It will now count down the right amount of time before emiting another batch of particles. - Calling
ParticleEmitter.startwouldn't reset the_frameCountervalue internally, meaning the new emission didn't restart from the first texture frame again. ParticleEmitter.countersis a new Float32Array property that is used to hold all of the various internal counters required for emitter operation. Both the previous_counterand_frameCounterproperties have been merged into this array, along with new ones required for new features.- The WebGL Renderer will now use the new
setQuadfeature 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.preDestroyis 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.destroyis a new method that will clean up all external references and destroy the Animation State controller.- The
ParticleEmitter._frameLengthproperty is now specified on the class, rather than added dynamically at run-time, helping preserve class shape. - The
ParticleEmitter.defaultFrameproperty has been removed as it's not required. - Calling
ParticleEmitter.setFrameno longer resets the internal_frameCountervalue 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.configFastMapproperty has been moved to a local var within theParticleEmitterJS 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.configOpMapproperty has been moved to a local var within theParticleEmitterJS file. It didn't need to be a property on the class itself, reducing the overall size of the class and saving memory. Particle.sceneis a new property that references the Scene the Particle Emitter belongs to.Particle.animsis a new property that is an instance of theAnimationStatecomponent.Particle.emitis 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.isCroppedis a new read-only property. Do not modify.Particle.setSizeToFrameis a new internal NOOP method. Do not call.ParticleEmitter.animsis a new property that contains the Animation keys that can be assigned to Particles.ParticleEmitter.currentAnimis a new property that contains the index of the current animation, as tracked in cycle playback.ParticleEmitter.randomAnimis a new boolean property that controls if the animations are selected randomly, or in a cycle.ParticleEmitter.animQuantityis a new property that controls the number of consecutive particles that are emitted with the current animation.ParticleEmitter.countersis a new internal Float32Array that holds all the counters the Emitter uses.ParticleEmitter.getAnimis a new method, called by Particles when they are emitted, that will return the animation to use, if any.ParticleEmitter.setAnimis a new method, called with the Emitter Manager, that sets the animation data into the Emitter.- The
Particles.EmitterOp.toJSONmethod will now JSON stringify the property value before returning it. Particles.EmitterOp.methodis a new property that holds the current operation method being used. This is a read-only numeric value.Particles.EmitterOp.activeis 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.getMethodis a new internal method that returns the operation function being used as a numeric value. This is then cached in themethodproperty.- The
Particles.EmitterOp.setMethodsmethod 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.onChangemethod will now use the cached 'method' property to avoid running through thesetMethodsfunction 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.setConfigis a new method that allows you to set the configuration of the Emitter. Previously this was known asfromJSON.- The
ParticleEmitter.setPositionmethod no longer changes the position of the particle emission point, but of the Emitter itself. - The
ParticleEmitter.setBoundsmethod has been renamed tosetParticleBounds. - The
ParticleEmitter.setSpeedmethod has been renamed tosetParticleSpeed. - The
ParticleEmitter.setScalemethod has been renamed tosetParticleScaleassetScalewill now set the scale of the whole Emitter. - The
ParticleEmitter.setScaleXandsetScaleYmethods have been removed. Please usesetParticleScale. - The
ParticleEmitter.setGravitymethod has been renamed tosetParticleGravity. - The
ParticleEmitter.setGravityXandsetGravityYmethods have been removed. Please usesetParticleGravity. - The
ParticleEmitter.setAlphamethod has been renamed tosetParticleAlphaassetAlphawill now set the alpha of the whole Emitter. - The
ParticleEmitter.setTintmethod has been renamed tosetParticleTint. - The
ParticleEmitter.setLifespanmethod has been renamed tosetParticleLifespan. - The
ParticleEmitter.onproperty has been renamed toemittingto avoid conflicts with the Event Emitter. - The
ParticleEmitter.xproperty has been renamed toparticleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.yproperty has been renamed toparticleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleXproperty has been renamed toparticleScaleXand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.scaleYproperty has been renamed toparticleScaleYand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.tintproperty has been renamed toparticleTintand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.alphaproperty has been renamed toparticleAlphaand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.angleproperty has been renamed toparticleAngleand is a new EmitterOp capable of being tweened. - The
ParticleEmitter.rotateproperty has been renamed toparticleRotateand 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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
RenderTargetclass 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.clearandrebindit 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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod is now passed the default pipeline and auto mobile setting from the Game Config.
Multi Tint Pipeline
- The
batchLinemethod 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.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
outTintEffectattribute 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. This should give most developers the same level of sequencing they had using Timelines, without the timing issues. - The
Tween.seekmethod 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 newseekmethod 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.originis now (0.5, 0.5) by default instead of (0, 0).The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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.alwaysEnabledproperty has been removed. It is no longer checked within theInputPluginand 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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow hands over most control of the framebuffers to the WebGLRenderer. - The
GameObjects.Components.Mask.createBitmapMaskmethod can now accept thex,y,textureandframeparameters new to the BitmapMask constructor. - Previously, calling
createBitmapMaskon 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
- The
Graphics.strokeRoundedRectandfillRoundedRectmethods can now accept negative values for the corner radius settings, in which case a concave corner is drawn instead (thanks @rexrainbow) AnimationManager.getAnimsFromTextureis 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.setLineSpacingis 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 alsoBitmapText.lineSpacingfor the property rather than the method.WebGLPipeline.vertexAvailableis a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.- The
TilemapandTilemapLayerclasses have a new methodgetTileCorners. 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.getAllPlayingis a new method that will return all currently playing sounds in the Sound Manager.Animation.showBeforeDelayis 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.resetPointersis 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.resetis a new method that will reset a Pointer instance back to its 'factory' settings.- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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 aDataManagerinstance 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
GenerateVertsfunction has a new optional parameterflipUVwhich, if set, will flip the UV texture coordinates (thanks cedarcantab) - The
GenerateVertsfunction no longer errors if the verts and uvs arrays are not the same size andcontainsZis true (thanks cedarcantab) - The
Device.Browserchecks 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.processQueuemethod will no longerreturnif 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.scrollXandscrollYwill now only set theCamera.dirtyflag totrueif 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.updateis a new method that updates each of the Face vertices. This is now called internally byFace.isInView.Vertex.resizeis a new method that will set the position and then translate the Vertex based on an identity matrix.- The
Vertex.updatemethod now returnsthisto allow it to be chained. - You can now optionally specify the
maxSpeedvalue in the Arcade Physics Group config (thanks @samme) - You can now optionally specify the
useDampingboolean in the Arcade Physics Group config (thanks @samme) - Removed the
HexagonalTileToWorldYfunction as it cannot work without an X coordinate. UseHexagonalTileToWorldXYinstead. - Removed the
HexagonalWorldToTileYfunction as it cannot work without an X coordinate. UseHexagonalWorldToTileXYinstead. - 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.getAllmethod used to require akeyparameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned. - The
WebAudioSoundManagerwill 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_RESTOREDGame Event has been removed and the WebGL Renderer no longer listens for thecontextrestoredDOM event, or has acontextRestoredHandlermethod. 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
TextandTileSpriteGame Objects no longer listen for theCONTEXT_RESTOREDevent and have had theironContextRestoredmethods removed. Scenes.Systems.canInputis a new internal method that determines if a Scene can receive Input events, or not. This is now used by theInputPlugininstead of the previousisActivetest. This allows a Scene to emit and handle input events even when it is runninginitorpreload. Previously, it could only do this aftercreatehad finished running. Fix #6123 (thanks @yaasinhamidi)- The
BitmapTextGame Object has two new read-only propertiesdisplayWidthanddisplayHeight. This allows the BitmapText to correctly use theGetBoundscomponent. - The
BitmapTextGame Object now has theGetBoundscomponent added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames) WebGLSnapshotwill 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.snapshotFramebufferand 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 methodsnapshotAreahas had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)Animation.stopis always called when a new animation is loaded, regardless if the animation was playing or not and thedelayCounteris reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)ScaleManager.listenershas been renamed todomlistenersto avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)Geom.Intersects.LineToLinewill no longer create an internalPointobject, as it's not required internally (thanks @Trissolo)- The
tempZoneused byGridAlignhas now hadsetOrigin(0, 0)applied to it. This leads to more accurate / expected zone placement when aligning grid items. - The
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- The
maxSpeedsetting 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.jsentry 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_UPDATEevent from firing after the transition is over. Fix #5550 (thanks @mijinc0 @samme) - Although not recommended, when adding a
LayerGame Object to anotherLayerGame Object, it will no longer error because it cannot find theremoveFromDisplayListfunction. Fix #5595 (thanks @tringcooler) - The
Actions.Spreadmethod will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV) - Calling
setDisplayOriginon aVideoGame Object would cause the origins to be set toNaNif 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
ImageFileloads 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
dataKeyto specify a part of a JSON file when usingload.packwould 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.advancedWordWrapfunction 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
HexagonalTileToWorldXYfunction as it was incorrect. Now returns world coordinates correctly. Tilemap.copywould 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.copywill now use theDeepCopyfunction to copy theTile.propertiesobject, as otherwise it just gets copied by reference.- Recoded the point conversion math in the
HexagonalWorldToTileXYfunction as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich) - Fixed the point conversion math in the
IsometricWorldToTileXYfunction 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.worldToTileXorworldToTileYon a Isometric or Hexagonal Tilemap will now always returnnullinstead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should useworldToTileXYinstead. - The
Game.headlessStepmethod will now resetSceneManager.isProcessingbeforePRE_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.setPointswas called with the exact same number of points as before, it wouldn't set thedirtyflag, meaning the vertices were not updated on the next render (thanks @stupot) Particle.firewill 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)
TextGame 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.destroyLayermethod would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme) MapDataandObjectLayerwill now enforce that theTilemap.objectsproperty 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
ParseJSONTiledfunction will now run aDeepCopyon 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.setFromHSVwould not change the membersh,sandv, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow) - When calling
GameObject.getPostPipelineand 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
nextAnimproperty could get set toundefinedwhich 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.clearit will now callremoveDebugon the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton) - The
Video.loadURLmethod wouldn't load the video or emit theVIDEO_CREATEDevent unlessnoAudiowas specified. A load event handler has been added to resolve this (thanks @samme) - If you create a repeating or looping
TimerEventwith adelayof zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan) - The
endFrameandstartFrameproperties of theSpriteSheetparser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the givenstartFrameso that is frame zero and end atendFrame, regardless how many other frames are in the sheet. - Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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)
BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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.removeHandlernow specifies the context forEvents.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would causesysreference 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.addChildCallbackmethod 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.equalswill now return the correct result. Previously, it would always returnfalse(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.strokeRoundedRectwould 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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
RenderTargetclass 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.clearandrebindit 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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod is now passed the default pipeline and auto mobile setting from the Game Config.
Multi Tint Pipeline
- The
batchLinemethod 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.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
outTintEffectattribute 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. This should give most developers the same level of sequencing they had using Timelines, without the timing issues. - The
Tween.seekmethod 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 newseekmethod 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.originis now (0.5, 0.5) by default instead of (0, 0).The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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.alwaysEnabledproperty has been removed. It is no longer checked within theInputPluginand 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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow hands over most control of the framebuffers to the WebGLRenderer. - The
GameObjects.Components.Mask.createBitmapMaskmethod can now accept thex,y,textureandframeparameters new to the BitmapMask constructor. - Previously, calling
createBitmapMaskon 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
BitmapText.setLineSpacingis 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 alsoBitmapText.lineSpacingfor the property rather than the method.WebGLPipeline.vertexAvailableis a new method that returns the number of vertices that can be added to the current batch before it will trigger a flush.- The
TilemapandTilemapLayerclasses have a new methodgetTileCorners. 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.getAllPlayingis a new method that will return all currently playing sounds in the Sound Manager.Animation.showBeforeDelayis 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.resetPointersis 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.resetis a new method that will reset a Pointer instance back to its 'factory' settings.- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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.scrollXandscrollYwill now only set theCamera.dirtyflag totrueif 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.updateis a new method that updates each of the Face vertices. This is now called internally byFace.isInView.Vertex.resizeis a new method that will set the position and then translate the Vertex based on an identity matrix.- The
Vertex.updatemethod now returnsthisto allow it to be chained. - You can now optionally specify the
maxSpeedvalue in the Arcade Physics Group config (thanks @samme) - You can now optionally specify the
useDampingboolean in the Arcade Physics Group config (thanks @samme) - Removed the
HexagonalTileToWorldYfunction as it cannot work without an X coordinate. UseHexagonalTileToWorldXYinstead. - Removed the
HexagonalWorldToTileYfunction as it cannot work without an X coordinate. UseHexagonalWorldToTileXYinstead. - 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.getAllmethod used to require akeyparameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned. - The
WebAudioSoundManagerwill 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_RESTOREDGame Event has been removed and the WebGL Renderer no longer listens for thecontextrestoredDOM event, or has acontextRestoredHandlermethod. 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
TextandTileSpriteGame Objects no longer listen for theCONTEXT_RESTOREDevent and have had theironContextRestoredmethods removed. Scenes.Systems.canInputis a new internal method that determines if a Scene can receive Input events, or not. This is now used by theInputPlugininstead of the previousisActivetest. This allows a Scene to emit and handle input events even when it is runninginitorpreload. Previously, it could only do this aftercreatehad finished running. Fix #6123 (thanks @yaasinhamidi)- The
BitmapTextGame Object has two new read-only propertiesdisplayWidthanddisplayHeight. This allows the BitmapText to correctly use theGetBoundscomponent. - The
BitmapTextGame Object now has theGetBoundscomponent added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames) WebGLSnapshotwill 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.snapshotFramebufferand 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 methodsnapshotAreahas had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)Animation.stopis always called when a new animation is loaded, regardless if the animation was playing or not and thedelayCounteris reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)ScaleManager.listenershas been renamed todomlistenersto avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)Geom.Intersects.LineToLinewill no longer create an internalPointobject, as it's not required internally (thanks @Trissolo)- The
tempZoneused byGridAlignhas now hadsetOrigin(0, 0)applied to it. This leads to more accurate / expected zone placement when aligning grid items. - The
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- The
Actions.Spreadmethod will now place the final item correctly and abort early if the array only contains 1 or 0 items (thanks @EmilSV) - Calling
setDisplayOriginon aVideoGame Object would cause the origins to be set toNaNif 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
ImageFileloads 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
dataKeyto specify a part of a JSON file when usingload.packwould 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.advancedWordWrapfunction 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
HexagonalTileToWorldXYfunction as it was incorrect. Now returns world coordinates correctly. Tilemap.copywould 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.copywill now use theDeepCopyfunction to copy theTile.propertiesobject, as otherwise it just gets copied by reference.- Recoded the point conversion math in the
HexagonalWorldToTileXYfunction as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich) - Fixed the point conversion math in the
IsometricWorldToTileXYfunction 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.worldToTileXorworldToTileYon a Isometric or Hexagonal Tilemap will now always returnnullinstead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should useworldToTileXYinstead. - The
Game.headlessStepmethod will now resetSceneManager.isProcessingbeforePRE_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.setPointswas called with the exact same number of points as before, it wouldn't set thedirtyflag, meaning the vertices were not updated on the next render (thanks @stupot) Particle.firewill 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)
TextGame 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.destroyLayermethod would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme) MapDataandObjectLayerwill now enforce that theTilemap.objectsproperty 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
ParseJSONTiledfunction will now run aDeepCopyon 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.setFromHSVwould not change the membersh,sandv, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow) - When calling
GameObject.getPostPipelineand 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
nextAnimproperty could get set toundefinedwhich 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.clearit will now callremoveDebugon the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton) - The
Video.loadURLmethod wouldn't load the video or emit theVIDEO_CREATEDevent unlessnoAudiowas specified. A load event handler has been added to resolve this (thanks @samme) - If you create a repeating or looping
TimerEventwith adelayof zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan) - The
endFrameandstartFrameproperties of theSpriteSheetparser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the givenstartFrameso that is frame zero and end atendFrame, regardless how many other frames are in the sheet. - Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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)
BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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.removeHandlernow specifies the context forEvents.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would causesysreference 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.addChildCallbackmethod 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.equalswill now return the correct result. Previously, it would always returnfalse(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.strokeRoundedRectwould 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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
RenderTargetclass 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.clearandrebindit 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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod is now passed the default pipeline and auto mobile setting from the Game Config.
Multi Tint Pipeline
- The
batchLinemethod 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.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
outTintEffectattribute 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. This should give most developers the same level of sequencing they had using Timelines, without the timing issues. - The
Tween.seekmethod 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 newseekmethod 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.originis now (0.5, 0.5) by default instead of (0, 0).The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow hands over most control of the framebuffers to the WebGLRenderer. - The
GameObjects.Components.Mask.createBitmapMaskmethod can now accept thex,y,textureandframeparameters new to the BitmapMask constructor. - Previously, calling
createBitmapMaskon 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
- The
TilemapandTilemapLayerclasses have a new methodgetTileCorners. 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.getAllPlayingis a new method that will return all currently playing sounds in the Sound Manager.Animation.showBeforeDelayis 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.resetPointersis 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.resetis a new method that will reset a Pointer instance back to its 'factory' settings.- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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
maxSpeedvalue in the Arcade Physics Group config (thanks @samme) - You can now optionally specify the
useDampingboolean in the Arcade Physics Group config (thanks @samme) - Removed the
HexagonalTileToWorldYfunction as it cannot work without an X coordinate. UseHexagonalTileToWorldXYinstead. - Removed the
HexagonalWorldToTileYfunction as it cannot work without an X coordinate. UseHexagonalWorldToTileXYinstead. - 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.getAllmethod used to require akeyparameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned. - The
WebAudioSoundManagerwill 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_RESTOREDGame Event has been removed and the WebGL Renderer no longer listens for thecontextrestoredDOM event, or has acontextRestoredHandlermethod. 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
TextandTileSpriteGame Objects no longer listen for theCONTEXT_RESTOREDevent and have had theironContextRestoredmethods removed. Scenes.Systems.canInputis a new internal method that determines if a Scene can receive Input events, or not. This is now used by theInputPlugininstead of the previousisActivetest. This allows a Scene to emit and handle input events even when it is runninginitorpreload. Previously, it could only do this aftercreatehad finished running. Fix #6123 (thanks @yaasinhamidi)- The
BitmapTextGame Object has two new read-only propertiesdisplayWidthanddisplayHeight. This allows the BitmapText to correctly use theGetBoundscomponent. - The
BitmapTextGame Object now has theGetBoundscomponent added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames) WebGLSnapshotwill 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.snapshotFramebufferand 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 methodsnapshotAreahas had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)Animation.stopis always called when a new animation is loaded, regardless if the animation was playing or not and thedelayCounteris reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)ScaleManager.listenershas been renamed todomlistenersto avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)Geom.Intersects.LineToLinewill no longer create an internalPointobject, as it's not required internally (thanks @Trissolo)- The
tempZoneused byGridAlignhas now hadsetOrigin(0, 0)applied to it. This leads to more accurate / expected zone placement when aligning grid items. - The
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- When
ImageFileloads 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
dataKeyto specify a part of a JSON file when usingload.packwould 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.advancedWordWrapfunction 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
HexagonalTileToWorldXYfunction as it was incorrect. Now returns world coordinates correctly. Tilemap.copywould 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.copywill now use theDeepCopyfunction to copy theTile.propertiesobject, as otherwise it just gets copied by reference.- Recoded the point conversion math in the
HexagonalWorldToTileXYfunction as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich) - Fixed the point conversion math in the
IsometricWorldToTileXYfunction 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.worldToTileXorworldToTileYon a Isometric or Hexagonal Tilemap will now always returnnullinstead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should useworldToTileXYinstead. - The
Game.headlessStepmethod will now resetSceneManager.isProcessingbeforePRE_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.setPointswas called with the exact same number of points as before, it wouldn't set thedirtyflag, meaning the vertices were not updated on the next render (thanks @stupot) Particle.firewill 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)
TextGame 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.sortGameObjectsmethod 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 InputalwaysEnableflag 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.destroyLayermethod would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme) MapDataandObjectLayerwill now enforce that theTilemap.objectsproperty 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
ParseJSONTiledfunction will now run aDeepCopyon 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.setFromHSVwould not change the membersh,sandv, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow) - When calling
GameObject.getPostPipelineand 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
nextAnimproperty could get set toundefinedwhich 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.clearit will now callremoveDebugon the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton) - The
Video.loadURLmethod wouldn't load the video or emit theVIDEO_CREATEDevent unlessnoAudiowas specified. A load event handler has been added to resolve this (thanks @samme) - If you create a repeating or looping
TimerEventwith adelayof zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan) - The
endFrameandstartFrameproperties of theSpriteSheetparser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the givenstartFrameso that is frame zero and end atendFrame, regardless how many other frames are in the sheet. - Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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)
BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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.removeHandlernow specifies the context forEvents.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would causesysreference 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.addChildCallbackmethod 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.equalswill now return the correct result. Previously, it would always returnfalse(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.strokeRoundedRectwould 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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
RenderTargetclass 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.clearandrebindit 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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod is now passed the default pipeline and auto mobile setting from the Game Config.
Multi Tint Pipeline
- The
batchLinemethod 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.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
outTintEffectattribute 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. This should give most developers the same level of sequencing they had using Timelines, without the timing issues. - The
Tween.seekmethod 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 newseekmethod 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.originis now (0.5, 0.5) by default instead of (0, 0).The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow hands over most control of the framebuffers to the WebGLRenderer. - The
GameObjects.Components.Mask.createBitmapMaskmethod can now accept thex,y,textureandframeparameters new to the BitmapMask constructor. - Previously, calling
createBitmapMaskon 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
- The
TilemapandTilemapLayerclasses have a new methodgetTileCorners. 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.getAllPlayingis a new method that will return all currently playing sounds in the Sound Manager.Animation.showBeforeDelayis 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.resetPointersis 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.resetis a new method that will reset a Pointer instance back to its 'factory' settings.- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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
maxSpeedvalue in the Arcade Physics Group config (thanks @samme) - You can now optionally specify the
useDampingboolean in the Arcade Physics Group config (thanks @samme) - Removed the
HexagonalTileToWorldYfunction as it cannot work without an X coordinate. UseHexagonalTileToWorldXYinstead. - Removed the
HexagonalWorldToTileYfunction as it cannot work without an X coordinate. UseHexagonalWorldToTileXYinstead. - 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.getAllmethod used to require akeyparameter, to return Sounds matching the key. This is now optional and if not given, all Sound instances are returned. - The
WebAudioSoundManagerwill 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_RESTOREDGame Event has been removed and the WebGL Renderer no longer listens for thecontextrestoredDOM event, or has acontextRestoredHandlermethod. 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
TextandTileSpriteGame Objects no longer listen for theCONTEXT_RESTOREDevent and have had theironContextRestoredmethods removed. Scenes.Systems.canInputis a new internal method that determines if a Scene can receive Input events, or not. This is now used by theInputPlugininstead of the previousisActivetest. This allows a Scene to emit and handle input events even when it is runninginitorpreload. Previously, it could only do this aftercreatehad finished running. Fix #6123 (thanks @yaasinhamidi)- The
BitmapTextGame Object has two new read-only propertiesdisplayWidthanddisplayHeight. This allows the BitmapText to correctly use theGetBoundscomponent. - The
BitmapTextGame Object now has theGetBoundscomponent added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames) WebGLSnapshotwill 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.snapshotFramebufferand 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 methodsnapshotAreahas had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)Animation.stopis always called when a new animation is loaded, regardless if the animation was playing or not and thedelayCounteris reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)ScaleManager.listenershas been renamed todomlistenersto avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)Geom.Intersects.LineToLinewill no longer create an internalPointobject, as it's not required internally (thanks @Trissolo)- The
tempZoneused byGridAlignhas now hadsetOrigin(0, 0)applied to it. This leads to more accurate / expected zone placement when aligning grid items. - The
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- When
ImageFileloads 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
dataKeyto specify a part of a JSON file when usingload.packwould 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.advancedWordWrapfunction 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
HexagonalTileToWorldXYfunction as it was incorrect. Now returns world coordinates correctly. Tilemap.copywould 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.copywill now use theDeepCopyfunction to copy theTile.propertiesobject, as otherwise it just gets copied by reference.- Recoded the point conversion math in the
HexagonalWorldToTileXYfunction as it was incorrect. Now detects any dimension hexagon correctly. Fix #5608 (thanks @stonerich) - Fixed the point conversion math in the
IsometricWorldToTileXYfunction 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.worldToTileXorworldToTileYon a Isometric or Hexagonal Tilemap will now always returnnullinstead of doing nothing, as you cannot convert to a tile index using just one coordinate for these map types, you should useworldToTileXYinstead. - The
Game.headlessStepmethod will now resetSceneManager.isProcessingbeforePRE_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.setPointswas called with the exact same number of points as before, it wouldn't set thedirtyflag, meaning the vertices were not updated on the next render (thanks @stupot) Particle.firewill 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)
TextGame 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.sortGameObjectsmethod 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 InputalwaysEnableflag 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.destroyLayermethod would throw an error "TypeError: layer.destroy is not a function". It now correctly destroys the TilemapLayer. Fix #6268 (thanks @samme) MapDataandObjectLayerwill now enforce that theTilemap.objectsproperty 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
ParseJSONTiledfunction will now run aDeepCopyon 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.setFromHSVwould not change the membersh,sandv, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow) - When calling
GameObject.getPostPipelineand 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
nextAnimproperty could get set toundefinedwhich 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.clearit will now callremoveDebugon the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton) - The
Video.loadURLmethod wouldn't load the video or emit theVIDEO_CREATEDevent unlessnoAudiowas specified. A load event handler has been added to resolve this (thanks @samme) - If you create a repeating or looping
TimerEventwith adelayof zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan) - The
endFrameandstartFrameproperties of theSpriteSheetparser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the givenstartFrameso that is frame zero and end atendFrame, regardless how many other frames are in the sheet. - Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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)
BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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.removeHandlernow specifies the context forEvents.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would causesysreference 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.addChildCallbackmethod 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.equalswill now return the correct result. Previously, it would always returnfalse(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.strokeRoundedRectwould 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod is now passed the default pipeline and auto mobile setting from the Game Config.
Multi Tint Pipeline
- The
Multi.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. This should give most developers the same level of sequencing they had using Timelines, without the timing issues. - The
Tween.seekmethod 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 newseekmethod 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely millisecond based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.originis now (0.5, 0.5) by default instead of (0, 0).The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow hands over most control of the framebuffers to the WebGLRenderer. - The
GameObjects.Components.Mask.createBitmapMaskmethod can now accept thex,y,textureandframeparameters 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
Animation.showBeforeDelayis 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.resetPointersis 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.resetis a new method that will reset a Pointer instance back to its 'factory' settings.- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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.canInputis a new internal method that determines if a Scene can receive Input events, or not. This is now used by theInputPlugininstead of the previousisActivetest. This allows a Scene to emit and handle input events even when it is runninginitorpreload. Previously, it could only do this aftercreatehad finished running. Fix #6123 (thanks @yaasinhamidi)- The
BitmapTextGame Object has two new read-only propertiesdisplayWidthanddisplayHeight. This allows the BitmapText to correctly use theGetBoundscomponent. - The
BitmapTextGame Object now has theGetBoundscomponent added to it, meaning you can now correctly get its dimensions as part of a Container. Fix #6237 (thanks @likwidgames) WebGLSnapshotwill 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.snapshotFramebufferand 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 methodsnapshotAreahas had this limitation removed as a result, allowing you to snapshot areas that are larger than the Canvas. Fix #5707 (thanks @teng-z)Animation.stopis always called when a new animation is loaded, regardless if the animation was playing or not and thedelayCounteris reset to zero. This stops animations with delays preventing other animations from being started until the delay has expired. Fix #5680 (thanks @enderandpeter)ScaleManager.listenershas been renamed todomlistenersto avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)Geom.Intersects.LineToLinewill no longer create an internalPointobject, as it's not required internally (thanks @Trissolo)- The
tempZoneused byGridAlignhas now hadsetOrigin(0, 0)applied to it. This leads to more accurate / expected zone placement when aligning grid items. - The
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- The method
Color.setFromHSVwould not change the membersh,sandv, only the RGB properties. It now correctly updates them both. Fix #6276 (thanks @rexrainbow) - When calling
GameObject.getPostPipelineand 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
nextAnimproperty could get set toundefinedwhich 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.clearit will now callremoveDebugon the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton) - The
Video.loadURLmethod wouldn't load the video or emit theVIDEO_CREATEDevent unlessnoAudiowas specified. A load event handler has been added to resolve this (thanks @samme) - If you create a repeating or looping
TimerEventwith adelayof zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan) - The
endFrameandstartFrameproperties of theSpriteSheetparser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the givenstartFrameso that is frame zero and end atendFrame, regardless how many other frames are in the sheet. - Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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)
BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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.removeHandlernow specifies the context forEvents.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would causesysreference 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.addChildCallbackmethod 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.equalswill now return the correct result. Previously, it would always returnfalse(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.strokeRoundedRectwould 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod 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 inMulti.frag. This new shader uses a function calledgetSamplerinstead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details. - The
Multi.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The
WebGL.Utils.parseFragmentShaderMaxTexturesfunction no longer supports the%forloop%declaration. - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely ms/time based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.originis now (0.5, 0.5) by default instead of (0, 0).The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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.listenershas been renamed todomlistenersto avoid conflicting with the EventEmitter listeners object. Fix #6260 (thanks @x-wk)Geom.Intersects.LineToLinewill no longer create an internalPointobject, as it's not required internally (thanks @Trissolo)- The
tempZoneused byGridAlignhas now hadsetOrigin(0, 0)applied to it. This leads to more accurate / expected zone placement when aligning grid items. - The
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- When calling
InputPlugin.clearit will now callremoveDebugon the Game Object, making sure it clears up any Input Debug Graphics left in the Scene. Fix #6137 (thanks @spayton) - The
Video.loadURLmethod wouldn't load the video or emit theVIDEO_CREATEDevent unlessnoAudiowas specified. A load event handler has been added to resolve this (thanks @samme) - If you create a repeating or looping
TimerEventwith adelayof zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan) - The
endFrameandstartFrameproperties of theSpriteSheetparser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the givenstartFrameso that is frame zero and end atendFrame, regardless how many other frames are in the sheet. - Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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)
BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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.removeHandlernow specifies the context forEvents.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would causesysreference 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.addChildCallbackmethod 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.equalswill now return the correct result. Previously, it would always returnfalse(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.strokeRoundedRectwould 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod 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 inMulti.frag. This new shader uses a function calledgetSamplerinstead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details. - The
Multi.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The
WebGL.Utils.parseFragmentShaderMaxTexturesfunction no longer supports the%forloop%declaration. - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely ms/time based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin CANVAS mode only would produce a nearly always black color due to float conversion (thanks @andymikulski) - Using
DynamicTexture.fillin CANVAS mode only, after using theerasemethod, wouldn't reset the global composite operation correctly, resulting in fills. Fix #6124 (thanks @mateuszkmiecik) - Drawing a frame via
draw,drawFrameorbatchDrawFrameand specifying atintvalue 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
- When using
Group.createMultipleit 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 parametersfromScene,toSceneanddurationallowing you to consolidate transition logic into a single callback, rather than split across the start and end events (thanks @rexrainbow) TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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
GetBitmapTextSizefunction now includes an extra property in the resultingBitmapTextCharacterobject calledidxwhich is the index of the character within the Bitmap Text, without factoring in any word wrapping (thanks @JaroVDH) Camera.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- The
Video.loadURLmethod wouldn't load the video or emit theVIDEO_CREATEDevent unlessnoAudiowas specified. A load event handler has been added to resolve this (thanks @samme) - If you create a repeating or looping
TimerEventwith adelayof zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan) - The
endFrameandstartFrameproperties of theSpriteSheetparser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the givenstartFrameso that is frame zero and end atendFrame, regardless how many other frames are in the sheet. - Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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)
BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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.removeHandlernow specifies the context forEvents.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would causesysreference 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.addChildCallbackmethod 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.equalswill now return the correct result. Previously, it would always returnfalse(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.strokeRoundedRectwould 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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.currentActiveTextureproperty has been removed. - The
WebGLRenderer.startActiveTextureproperty has been removed. - The
WebGLRenderer.tempTexturesproperty has been removed. - The
WebGLRenderer.textureZeroproperty has been removed. - The
WebGLRenderer.normalTextureproperty has been removed. - The
WebGLRenderer.textueFlushproperty has been removed. - The
WebGLRenderer.isTextureCleanproperty has been removed. - The
WebGLRenderer.setBlankTexturemethod has been removed. - The
WebGLRenderer.setTextureSourcemethod has been removed. - The
WebGLRenderer.isNewNormalMapmethod has been removed. - The
WebGLRenderer.setTextureZeromethod has been removed. - The
WebGLRenderer.clearTextureZeromethod has been removed. - The
WebGLRenderer.setNormalMapmethod has been removed. - The
WebGLRenderer.clearNormalMapmethod has been removed. - The
WebGLRenderer.unbindTexturesmethod has been removed. - The
WebGLRenderer.resetTexturesmethod has been removed. - The
WebGLRenderer.setTexture2Dmethod has been removed. - The
WebGLRenderer.pushFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.setFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.popFramebuffermethod has had theresetTexturesargument removed. - The
WebGLRenderer.deleteTexturemethod has had theresetargument removed. - The
Textures.TextureSource.glIndexproperty has been removed. - The
Textures.TextureSource.glIndexCounterproperty 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.vertandshaders/Mobile.fragare the two shaders used for the Mobile Pipeline.PipelineManager#MOBILE_PIPELINEis a new constant-style reference to the Mobile Pipeline instance.autoMobilePipelineis 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 tofalseto force use of the Multi Tint pipeline (or if you need more advanced conditions to check when to enable it)defaultPipelineis 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.defaultis a new propery that is used by most Game Objects to determine which pipeline they will init with.PipelineManager.setDefaultPipelineis 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.bootmethod 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 inMulti.frag. This new shader uses a function calledgetSamplerinstead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details. - The
Multi.fragshader now uses ahighpprecision, ormediumpif the device doesn't support it (thanks @arbassic) - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The
WebGL.Utils.parseFragmentShaderMaxTexturesfunction no longer supports the%forloop%declaration. - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally. - Previously, the Multi Tint methods
batchSprite,batchTexture,batchTextureFrameandbatchFillRectwould all make heavy use of theTransformMatrix.getXRoundandgetYRoundmethods, which in turn calledgetXandgetYand 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
maxLightscopies 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.fragshader now uses a newuLightCountuniform to know when to stop iterating through the max lights. - The
LightPipeline.LIGHT_COUNTconstant has been removed as it's not used internally. - The
LightPipelineprevious created a global level temporary vec2 for calculations. This is now part of the class as the newtempVec2property.
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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely ms/time based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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.Textureclass, 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.isDrawingis a new boolean that allows you to tell if a batch draw has been started and is in process.DynamicTexture.isSpriteTextureis 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.setIsSpriteTextureis a new method that allows you to toggle theisSpriteTextureproperty in a chained manner.DynamicTexture.renderTargetis 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.stampis 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.repeatis 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)batchGameObjectnow splits based on the renderer, allowing us to combine lots of the rendering code together, saving space.- The
snapshotandsnapshotPixelmethods now use thesnapshotAreamethod to reduce code and filesize. - The
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) DynamicTexture.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)- Using
DynamicTexture.fillin 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
keyandframearguments 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
RenderTextureproperties have changed:rendereris now available viatexture.renderer.textureManagerhas been removed.globalTinthas been removed.globalAlphahas been removed.canvasis now available viatexture.canvas.contextis now available viatexture.context.dirtyis now available viatexture.dirty.camerais now available viatexture.camera.renderTargetis now available viatexture.renderTarget.The following
RenderTexturemethods have changed:drawGameObjecthas been removed, this is now handled by the batch methods.resizehas been renamed. UsesetSize(width, height)instead.setGlobalTinthas been removed as it's no longer used internally.setGlobalAlphahas been removed as it's no longer used internally.batchGameObjectWebGLhas been removed, now handled bybatchGameObject.batchGameObjectCanvashas been removed, now handled bybatchGameObject.
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
BitmapMaskconstructor is now capable of creating an Image Game Object from the new optional arguments:x, y, texture, frameif 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,mainFramebufferandmaskFramebuffer. The following methods have also been removed:createMaskandclearMask. - The
WebGLRendererhas 2 new properties:maskSourceandmaskTarget. These are the new global mask framebuffers. WebGLRenderer.beginBitmapMaskis a new method that starts the process of using the mask target framebuffer for drawing. This is called by theBitmapMaskPipeline.WebGLRenderer.drawBitmapMaskis a new method that completes the process of rendering using the mask target framebuffer. This is called by theBitmapMaskPipeline.- The
BitmapMaskPipelinenow 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
TextureManager.silentWarningsis 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.parseFrameis 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.stableSortandDevice.features.stableSortis a new property that will control if the internal depth sorting routine uses our own StableSort function, or the built-in browserArray.sort. Only modern browsers have a stableArray.sortimplementation, 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.es2019is 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
sourceparameter:addSpriteSheet,addAtlas,addAtlasJSONArray,addAtlasJSONHash,addAtlasXMLandaddAtlasUnity. 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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.isSceneCamerais a new boolean that controls if the Camera belongs to a Scene (the default), or a Texture. You can set this via theCamera.setScenemethod. Once set theCamera.updateSystemmethod is skipped, preventing the WebGL Renderer from setting a scissor every frame.Camera.preRenderwill now applyMath.floorinstead ofMath.roundto the values, keeping it consistent with the Renderer when following a sprite.- When rendering a Sprite with a Camera set to
roundPixelsit will now runMath.flooron the Matrix position, preventing you from noticing 'jitters' as much when Camera following sprites in heavily zoomed Camera systems. TransformMatrix.setQuadis 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 newTransformMatrix.quadFloat32Array, which is also returned from this method.TransformMatrix.multiplynow directly updates the Float32Array, leading to 6 less getter invocations.- The
CameraManager.getVisibleChildrenmethod now uses the native Array filter function, rather than a for loop. This should improve performance in some cases (thanks @JernejHabjan) SceneManager.systemSceneis 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.getmethof can now accept aFrameinstance as its parameter, which will return the frames parent Texture. - The
GameObject.setFramemethod can now accept aFrameinstance as its parameter, which will also automatically update the Texture the Game Object is using. Device.safariVersionis 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.BitmapMaskdestroymethod will now remove the context-lost event handler. - The
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.sceneis a new property that allows the Bitmap Mask to reference the Scene it was created in.- The
DOMElement.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme) - The
Texture.destroymethod will only destroy sources, dataSources and frames if they exist, protecting against previously destroyed instances.
Bug Fixes
- If you create a repeating or looping
TimerEventwith adelayof zero it will now throw a runtime error as it would lead to an infinite loop. Fix #6225 (thanks @JernejHabjan) - The
endFrameandstartFrameproperties of theSpriteSheetparser wouldn't correctly apply themselves, the Texture would still end up with all of the frames. It will now start at the givenstartFrameso that is frame zero and end atendFrame, regardless how many other frames are in the sheet. - Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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)
BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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.removeHandlernow specifies the context forEvents.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would causesysreference 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.addChildCallbackmethod 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.equalswill now return the correct result. Previously, it would always returnfalse(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.strokeRoundedRectwould 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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 inMulti.frag. This new shader uses a function calledgetSamplerinstead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details. - The
Multi.fragshader now uses ahighpprecision instead ofmediump. - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The
WebGL.Utils.parseFragmentShaderMaxTexturesfunction no longer supports the%forloop%declaration. - The internal WebGL Utils function
GenerateSrchas 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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty 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
chainmethod. 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,repeatandrepeatDelay. These should be numbers only. You can, however, still provide a function fordelay, to keep it compatible with the StaggerBuilder. - The
TweenManager#getAllTweensmethod has been renamed toTweenManager#getTweens. Functionally, it is the same. - The property and feature
Tween.useFrameshas been removed and is no longer a valid Tween Config option. Tweens are now entirely ms/time based. - The
TweenOnUpdateCallbacknow 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 theonUpdateParamsarray when the Tween was created. - The
TweenOnYoyoCallbacknow 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 theonYoyoParamsarray when the Tween was created. - The
TweenOnRepeatCallbacknow 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 theonRepeatParamsarray when the Tween was created. Tween.stophas had theresetToparameter removed from it. Callingstopon a Tween will now prepare the tween for immediate destruction. If you only wish to pause the tween, seeTween.pauseinstead.- 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
persistsboolean flag when creating it, or toggle theTween.persistproperty 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,onUpdateScopeandonYoyoScope. You should set thecallbackScopeproperty instead, which will globally set the scope for all callbacks. You can also set theTween.callbackScopeproperty.
The following are to do with the new Chained Tweens feature:
TweenManager.chain- TODOTween.getChainedTweensis 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.addandTweenManager.createcan 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.pauseis a new method that allows you to pause a Tween. This will emit the PAUSE event and, if set, fire theonPausecallback.Tween.resumeis a new method that allows you to resume a paused Tween. This will emit the RESUME event and, if set, fire theonResumecallback.- There is a new
TweenOnPauseCallbackavailable when creating a Tween (via theonPauseproperty). This comes with associatedonPauseParamsandonPauseScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. This callback is invoked if you pause the Tween. - There is a new
TweenOnResumeCallbackavailable when creating a Tween (via theonResumeproperty). This comes with associatedonResumeParamsandonResumeScopeproperties, too, like all other callbacks and can also be added via theTween.setCallbacksmethod. 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
interpolationproperty 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 includeslinear,bezierandcatmull(orcatmullrom), or you can provide your own function to use. - You can now specify a
scaleproperty in a Tween config and, if the target does not have ascaleproperty itself (i.e. a GameObject) then it will automatically apply the value to bothscaleXandscaleYtogether 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 thetargetparameter. 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 theparamsargument would cause an error invoking the callback params. This parameter is now fully optional. Fix #6047 (thanks @orcomarcio) - Calling
Tween.playimmediately after creating a tween withpaused: truein the config wouldn't start playback. Fix #6005 (thanks @MartinEyebab) - Fixed an issue where neither Tweens or Timelines would factor in the Tween Manager
timeScalevalue unless they were using frame-based timing instead of delta timing. - The first parameter to
Tween.seek,toPositionnow defaults to zero. Previously, you had to specify a value. - The
TweenBuildernow uses the newGetInterpolationFunctionfunction internally. - The
TweenBuilderhas been optimized to perform far less functions when creating the TweenData instances. - The keyword
interpolationhas been added to the Reserved Words list and Defaults list (it defaults tonull). - The keyword
persistshas been added to the Reserved Words list and Defaults list (it defaults tofalse). Tween.initTweenDatais a new method that handles the initialisation of all the Tween Data and Tween values. This replaces what took place in theinitandseekmethods previously. This is called automatically and should not usually be invoked directly.- The internal
Tween.calcDurationmethod has been removed. This is now handled as part of theinitTweenDatacall. - Fixed a bug where setting
repeatandholdwould 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._limitRateis a new internal private property allowing the Timestep to keep track of fps-limited steps.TimeStep.hasFpsLimitis a new internal boolean so the Timestep knows if the step is fps rate limited, or not.- There is now a
TimeStep.stepmethod andTimeStep.setLimitFPSmethod. Which one is called depends on if you have fps limited your game, or not. This switch is made internally, automatically. TimeStep.smoothDeltais a new method that encapsulates the delta smoothing.TimeStep.updateFPSis a new method that calculates the moving frame rate average.TimeStep.wakewill now automatically reset the fps limits and internal update counters.TimeStep.destroywill now callRequestAnimationFrame.destroy, properly cleaning it down.RequestAnimationFrame.stepwill now no longer callrequestAnimationFrameifisRunninghas been set tofalse(via thestopmethod)- The
TimeStepno longer calculates or passes theinterpolationvalue to Game.step as it was removed several versions ago, so is redundant. - The
RequestAnimationFrame.tickproperty has been removed as it's no longer used internally. - The
RequestAnimationFrame.lastTimeproperty has been removed as it's no longer used internally. - The
RequestAnimationFrameclass no longer calculates the tick or lastTime values and doesn't callperformance.nowas these values were never used internally and were not used by the receiving callback either. - The
RequestAnimationFrame.targetproperty has been renamed todelayto better describe what it does. - The TimeStep would always allocate 1 more entry than the
deltaSmoothingMaxvalue set in the game config. This is now clamped correctly (thanks @vzhou842)
New Features
- The
TextureManager.addSpriteSheetmethod 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.pauseis a new method that will pause the entire game and all Phaser systems.Game.resumeis a new method that will resume the entire game and resume all of Phaser's systems.RenderTexture.fillFrameis 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.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.setIsSpriteTextureis 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.blitFramehas a new optional boolean parameterflipYwhich, if set, will invert the source Render Target while drawing it to the destination Render Target.GameObjects.Polygon.setTois a new method that allows you to change the points being used to render a Polygon Shape Game Object. Fix #6151 (thanks @PhaserEditor2D)maxAliveParticlesis 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.Flattenis a new function that will return a flattened version of an array, regardless of how deeply-nested it is.GameObjects.Text.appendTextis 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_KEYis 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_KEYis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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.BitmapMaskdestroymethod will now remove the context-lost event handler. - The
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.sceneis a new property that allows the Bitmap Mask to reference the Scene it was created in.- The
DOMElement.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.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
TextStyleconfiguration object to the Text Game ObjectssetStylemethod, it would ignore anymetricsdata it may contain and reset it back to the defaults. It will now respect themetricsconfig and use it, if present. Fix #6149 (thanks @michalfialadev) - A Texture
ScaleModewill now override the Game Configantialiassetting under the Canvas Renderer, where-as before ifantialiaswastruethen it would ignore the scale mode of the texture (thanks @Cirras) - The
Device.Audiomodule has been rewritten to use a new internalCanPlayfunction that cuts down on the amount of code required greatly. Device.Audio.aacis 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.flacis 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 callBody.checkWorldBoundsas 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
CanvasFeaturesfor thecheckInverseAlphatest is now removed from the CanvasPool after use. - The
CanvasFeaturestests and the TextureManager_tempContextnow specify the{ willReadFrequently: true }hint to inform the browser the canvas is to be read from, not composited. - When calling
TextureManager.getTextureKeysit will now exclude the default__WHITEtexture 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
snapshotPixelfunction, used by the Canvas and WebGL Renderers and the RenderTexture would mistakenly divide the alpha value. These values now return correctly (thanks @samme) - The
NoAudioSoundManagernow has all of the missing methods, such asremoveAllandgetto allow it to be a direct replacement for the HTML5 and WebAudio Sound Managers (thanks @orjandh @samme)
Bug Fixes
- Destroying a
WebAudioSoundin the same game step as destroying the Game itself would cause an error when trying to disconnect already disconnected Web Audio nodes.WebAudioSoundwill now bail out of its destroy sequence if it's already pending removal. Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.fillin 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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.removeHandlernow specifies the context forEvents.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would causesysreference 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.addChildCallbackmethod 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.equalswill now return the correct result. Previously, it would always returnfalse(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.strokeRoundedRectwould 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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 inMulti.frag. This new shader uses a function calledgetSamplerinstead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details. - The
Multi.fragshader now uses ahighpprecision instead ofmediump. - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The
WebGL.Utils.parseFragmentShaderMaxTexturesfunction no longer supports the%forloop%declaration. - The internal WebGL Utils function
GenerateSrchas 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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty has been removed as it's no longer used.
New Features
ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis a new method that will project the vector onto the given vector (thanks @samme)- Experimental feature: The
TilemapLayernow has theMaskcomponent - meaning you can apply a mask to tilemaps (thanks @samme) TilemapLayer.setTintis 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.setIsSpriteTextureis 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 propertyisSpriteTextureas 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.blitFramehas a new optional boolean parameterflipYwhich, 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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.BitmapMaskdestroymethod will now remove the context-lost event handler. - The
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.sceneis a new property that allows the Bitmap Mask to reference the Scene it was created in.- The
DOMElement.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin 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
LightGame Object now has theOriginandTransformcomponents, along with 4 new properties:width,height,displayWidthanddisplayHeight. This allows you to add a Light to a Container, or enable it for physics. Fix #6126 (thanks @jcoppage) - The
TransformComponent has a new boolean read-only propertyhasTransformComponentwhich is set totrueby default. - The Arcade Physics
World.enableBodymethod will now only create and add aBodyto an object if it has the Transform component, tested by checking thehasTransformComponentproperty. Without the Transform component, creating a Body would error with NaN values, causing the rest of the bodies in the world to fail. ProcessQueue.isActiveis a new method that tests if the given object is in the active list, or not.ProcessQueue.isPendingis a new method that tests if the given object is in the pending insertion list, or not.ProcessQueue.isDestroyingis a new method that tests if the given object is pending destruction, or not.ProcessQueue.addwill no longer place the item into the pending list if it's already active or pending.ProcessQueue.removewill check if the item is in the pending list, and simply remove it, rather than destroying it.Container.addHandlerwill now callGameObject.addedToScene.Container.removeHandlerwill now callGameObject.removedFromScene.
Bug Fixes
Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.fillin 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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.removeHandlernow specifies the context forEvents.DESTROY, fixing an issue where objects moved from one container, to another, then destroyed, would causesysreference 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.addChildCallbackmethod 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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 inMulti.frag. This new shader uses a function calledgetSamplerinstead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details. - The
Multi.fragshader now uses ahighpprecision instead ofmediump. - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The
WebGL.Utils.parseFragmentShaderMaxTexturesfunction no longer supports the%forloop%declaration. - The internal WebGL Utils function
GenerateSrchas 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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty has been removed as it's no longer used.
New Features
ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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.BitmapMaskdestroymethod will now remove the context-lost event handler. - The
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.sceneis a new property that allows the Bitmap Mask to reference the Scene it was created in.- The
DOMElement.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin real-time (thanks @spayton)
Bug Fixes
Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.fillin 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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 inMulti.frag. This new shader uses a function calledgetSamplerinstead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details. - The
Multi.fragshader now uses ahighpprecision instead ofmediump. - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The
WebGL.Utils.parseFragmentShaderMaxTexturesfunction no longer supports the%forloop%declaration. - The internal WebGL Utils function
GenerateSrchas 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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty has been removed as it's no longer used.
New Features
ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.projectis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich is used to ensure Files aren't flagged for destruction more than once. LoaderPlugin.localSchemesis a new array of scheme strings that the Loader considers as being local files. This is populated by the newPhaser.Core.Config#loaderLocalSchemegame / 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.BitmapMaskdestroymethod will now remove the context-lost event handler. - The
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.sceneis a new property that allows the Bitmap Mask to reference the Scene it was created in.- The
DOMElement.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, 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.strokeColorin real-time (thanks @spayton)
Bug Fixes
Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.fillin 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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.modein the Game Config would be ignored. It now accepts either this, orscaleModedirectly. Fix #5970 (thanks @samme) - The frame duration calculations in the
AnimationManager.createFromAsepritemethod would be incorrect if they contained a mixture of long and very short duration frames (thanks @martincapello) - The
TilemapLayer.getTilesWithinShapemethod would not return valid results when used with a Line geometry object. Fix #5640 (thanks @hrecker @samme) - Modified the way Phaser uses
requirestatements in order to fix an issue in Google's closure-compiler when variables are re-assigned to new values (thanks @TJ09) - When creating a
MatterTileBodyfrom an isometric tile the tiles top value would be incorrect. ThegetTopmethod 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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 inMulti.frag. This new shader uses a function calledgetSamplerinstead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details. - The
Multi.fragshader now uses ahighpprecision instead ofmediump. - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The
WebGL.Utils.parseFragmentShaderMaxTexturesfunction no longer supports the%forloop%declaration. - The internal WebGL Utils function
GenerateSrchas 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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty has been removed as it's no longer used.
New Features
ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich 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.BitmapMaskdestroymethod will now remove the context-lost event handler. - The
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.sceneis a new property that allows the Bitmap Mask to reference the Scene it was created in.- The
DOMElement.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods 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
disableContextMenufunction, 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.resetmethod no longer resets theKey.enabledorKey.preventDefaultbooleans back totrueagain, but only resets the state of the Key. Fix #6098 (thanks @descodifica)
Bug Fixes
Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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.fillin 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.
moveToXandmoveToYnow default to null instead of 0 (thanks @samme) - Layers will now destroy more carefully when children destroy themselves (thanks @rexrainbow)
- An error in the
GetBitmapTextSizefunction caused kerning to not be applied correctly to Bitmap Text objects. This now works across WebGL and Canvas (thanks @arbassic @TJ09) WebGLSnapshotandCanvasSnapshotwill now Math.floor the width/height values to ensure no sub-pixel dimensions, which corrupts the resulting texture. Fix #6099 (thanks @orjandh)ContainerCanvasRendererwould pass in a 5thcontainerparameter to the childrenderCanvascall, which was breaking theGraphicsCanvasRendererand isn't needed by any Game Object, so has been removed. Fix #6093 (thanks @Antriel)- Fixed issue in
Utils.Objects.GetValuewhere it would return an incorrect result if asourceandaltSourcewere 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.moveAboveandmoveBelowmethods 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific properties and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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 inMulti.frag. This new shader uses a function calledgetSamplerinstead. Please see the shader code and update your own shaders accordingly. You can also see the documentation for the MultiPipeline for details. - The
Multi.fragshader now uses ahighpprecision instead ofmediump. - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The
WebGL.Utils.parseFragmentShaderMaxTexturesfunction no longer supports the%forloop%declaration. - The internal WebGL Utils function
GenerateSrchas 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.Gridwith a faster and more efficient broadphase inMatter.Detector. - Reduced memory usage and garbage collection.
- Resolves issues in
Matter.SATrelated to collision reuse. - Removes performance issues from
Matter.Grid. - Improved collision accuracy.
MatterPhysics.collisionis a new reference to theCollisionmodule, which now handles all Matter collision events.MatterPhysics.gridhas been removed as this is now handled by theCollisionmodule.MatterPhysics.sathas been removed as this is now handled by theCollisionmodule.- The
Matter.Body.previousPositionImpulseproperty has been removed as it's no longer used.
New Features
ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.resetis 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
Videoconfig will now detect forx-m4vplayback support for video formats and store it in theVideo.m4vproperty. This is used automatically by theVideoFilefile loader. Fix #5719 (thanks @patrickkeenan) - The
KeyboardPlugin.removeKeymethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for the given Key. Fix #5693 (thanks @cyantree) - The
KeyboardPlugin.removeAllKeysmethod has a new optional parameterremoveCapture. This will remove any keyboard capture events for all of the Keys owned by the plugin. WebGLShader.fragSrcis a new property that holds the source of the fragment shader.WebGLShader.vertSrcis a new property that holds the source of the vertex shader.WebGLShader#.createProgramis 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.setBooleanis a new method that allows you to set a boolean uniform on a shader.WebGLPipeline.setBooleanis a new method that allows you to set a boolean uniform on a shader.Phaser.Scenes.Systems.getStatusis a new method that will return the current status of the Scene.Phaser.Scenes.ScenePlugin.getStatusis a new method that will return the current status of the given Scene.Math.LinearXYis a new function that will interpolate between 2 given Vector2s and return a new Vector2 as a result (thanks @GregDevProjects)Curves.Path.getCurveAtis a new method that will return the curve that forms the path at the given location (thanks @natureofcode)- You can now use any
ShapeGame Object as a Geometry Mask. Fix #5900 (thanks @rexrainbow) Mesh.setTintis a new method that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.tintis a new setter that will set the tint color across all vertices of a Mesh (thanks @rexrainbow)Mesh.clearTintis 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.GetLineToLinemethod has a new optional parameterisRay. Iftrueit will treat the first line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPointsmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). - The
Geom.Intersects.GetLineToPolygonmethod has a new optional parameterisRay. Iftrueit will treat the line parameter as a ray, if false, as a line segment (the default). Geom.Intersects.GetRaysFromPointToPolygonuses the newisRayparameter to enable this function to work fully again.
Loader Updates
MultiFile.pendingDestroyis a new method that is called by the Loader Plugin and manages preparing the file for deletion. It also emits theFILE_COMPLETEandFILE_KEY_COMPLETEevents, fixing a bug whereMultiFilerelated files, such as an Atlas JSON or a Bitmap Font File, wouldn't emit thefilecompleteevents for the parent file, only for the sub-files. This means you can now listen for the file completion event formultiatlasfiles, among others.MultiFile.destroyis a new method that clears down all external references of the file, helping free-up resources.File.addToCacheno longer callsFile.pendingDestroy, instead this is now handled by the Loader Plugin.- There is a new File constant
FILE_PENDING_DESTROYwhich 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.BitmapMaskdestroymethod will now remove the context-lost event handler. - The
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.sceneis a new property that allows the Bitmap Mask to reference the Scene it was created in.- The
DOMElement.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopandsleepwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel) - The
ScriptFileLoader 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.pausewill 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.addVerticeswill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)Mesh.addVerticesFromObjwill now throw a console warning if invalid vertices data is given to the method (thanks @omniowl)TouchManager.onTouchOverandonTouchOuthave been removed, along with all of their related event calls as they're not used by any browser any more.TouchManager.isTopis 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.onTouchMovemethod will now check if the changed touch is over the canvas, or not, via the DOMelementFromPointfunction. This means if the touch leaves the canvas, it will now trigger theGAME_OUTandGAME_OVERevents, 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.createBlankDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createDynamicLayerhas now been removed as it was deprecated in 3.50.TileMap.createStaticLayerhas now been removed as it was deprecated in 3.50.Animations.AnimationManager.createFromAsepritehas a new optional 3rd parametertarget. This allows you to create the animations directly on a Sprite, instead of in the global Animation Manager (thanks Telemako)Animations.AnimationState.createFromAsepriteis 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
pathpackage used by the TS Defs generator has been moved todevDependencies(thanks @antkhnvsk) - The
GetValuefunction has a new optional parameteraltSourcewhich allows you to provide an alternative object to source the value from. - The
Renderer.Snapshot.WebGLfunction has had its first parameter changed from anHTMLCanvasElementto aWebGLRenderingContext. This is now passed in from thesnapshotmethods inside the WebGL Renderer. The change was made to allow it to work with WebGL2 custom contexts (thanks @andymikulski)
Bug Fixes
Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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.setScalewould set thescaleYproperty tonull, causing calls tosetScaleYto throw a runtime error.scaleYis 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.resetwhen a tween was in a state ofPENDING_REMOVEwould cause it to fail to restart. It now restarts fully. Fix #4793 (thanks @spayton) - The default
Tween._pausedStatehas changed fromINITtoPENDING_ADD. This fixes a bug where if you calledTween.playimmediately after creating it, it would force the tween to freeze. Fix #5454 (thanks @michal-bures) - If you start a
PathFollowerwith atovalue it will now tween and complete at that value, rather than the end of the path as before (thanks @samme) Textwith 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.fromJSONfunction 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.stopListenersforgot to remove thetouchcancelhandler. This is now removed correctly (thanks @teng-z) - The
BitmapMaskshader 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.sortGameObjectswill 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 withalwaysEnabledset to true. This fixes an issue where non-render list objects would be skipped. Fix #5507 (thanks @EmilSV) - The
GameObject.willRendermethod will now factor in the parentdisplayList, 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.disablewill 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 matchenable. Fix #5828 (thank @natureofcode @thewaver)- The
GetBoundscomponent has been removed from the Point Light Game Object. Fix #5934 (thanks @x-wk @samme) SceneManager.moveAboveandmoveBelownow take into account the modified indexes after the move (thanks @EmilSV)- When forcing a game to use
setTimeoutand then sending the game to sleep, it would accidentally restart by using Request Animation Frame instead (thanks @andymikulski) - Including a
renderobject within the Game Config will no longer erase any top-level config render settings. Therenderobject 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.SafeRangefunction 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.pointToContainermethod would ignore the providedoutputparameter, but now uses it (thanks @vforsh) - The
PolygonGame Object would ignore itsclosePathproperty 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.batchTextureFramewill now skip thedrawImagecall in canvas if the frame width or height are zero. Fix #5951 (thanks @Hoshinokoe)BlitterCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.ParticleManagerCanvasRendererwill now skip thedrawImagecall in canvas if the frame width or height are zero.CanvasSnapshotwill now skip thedrawImagecall in canvas if the frame width or height are zero.TextureManager.getBase64will now skip thedrawImagecall in canvas if the frame width or height are zero.TilemapLayerCanvasRendererwill now skip thedrawImagecall 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific propertis and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill now automatically set the wrapping mode to clamp.WebGLPipeline.flipProjectionMatrixis a new method that allows you to flip the y and bottom projection matrix values via a parameter.PipelineManager.renderTargetsis a new property that holds an array ofRenderTargetobjects that allSpriteFXpipelines can share, to keep texture memory as low as possible.PipelineManager.maxDimensionis a new property that holds the largest possible target dimension.PipelineManager.frameIncis a new property that holds the amount theRenderTargets 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.targetIndexis 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
RenderTargetobjects during itsbootmethod. These are sized incrementally from 32px and up (use theframeIncvalue to alter this). These targets are shared by all Sprite FX Pipelines. PipelineManager.getRenderTargetis a new method that will return the aRenderTargetthat best fits the dimensions given. This is typically called by Sprite FX Pipelines, rather than directly.PipelineManager.getSwapRenderTargetis a new method that will return a 'swap'RenderTargetthat matches the size of the main target. This is called by Sprite FX pipelines and not typically called directly.PipelineManager.getAltSwapRenderTargetis a new method that will return a 'alternative swap'RenderTargetthat 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis 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 inMulti.frag. This new shader uses a function calledgetSamplerinstead of the often massive if/else glsl blocks from before. Please see the shader code and update your own shaders accordingly. - The
Multi.fragshader now uses ahighpprecision instead ofmediump. - The
WebGL.Utils.checkShaderMaxfunction will no longer use a massive if/else glsl shader check and will instead rely on the value given ingl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS). - The
WebGL.Utils.parseFragmentShaderMaxTexturesfunction no longer supports the%forloop%declaration. - The internal WebGL Utils function
GenerateSrchas been removed as it's no longer required internally.
New Features
ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.BitmapMaskdestroymethod will now remove the context-lost event handler. - The
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.sceneis a new property that allows the Bitmap Mask to reference the Scene it was created in.- The
DOMElement.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API. - A new
console.errorwill be printed if theFile,MultiFile,JSONFileorXMLFilefail to process or parse correctly, even if they manage to load. Fix #5862 #5851 (thanks @samme @ubershmekel)
Bug Fixes
Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame Objects would call the pre and post batch functions twice by mistake, potentially applying a post fx twice to them. ScaleManager.getParentBoundswill now also check to see if the canvas bounds have changed x or y position, and if so returntrue, 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.bootScenemethod will now always callLoaderPlugin.start, even if there are no files in the queue. This means that the Loader will always dispatch itsSTARTandCOMPLETEevents, even if the queue is empty because the files are already cached. You can now rely on theSTARTandCOMPLETEevents to be fired, regardless, using them safely in your preload scene. Fix #5877 (thanks @sipals) - Calling
TimerEvent.resetin 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
renderTargetsin a WebGL Pipeline config, you can now set optionalwidthandheightproperties, which will create a Render Target of that exact size, ignoring thescalevalue (if also given). WebGLPipeline.isSpriteFXis a new boolean property that defines if the pipeline is a Sprite FX Pipeline, or not. The default isfalse.GameObjects.Components.FXis a new component that provides access to FX specific propertis and methods. The Image and Sprite Game Objects have this component by default.fxPaddingand its related methodsetFXPaddingallow 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.setShadermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound before the shader is activated. - The
WebGLPipeline.setVertexBuffermethod has a new optional parameterbufferthat allows you to set the vertex buffer to be bound if you don't want to bind the default one. - The
WebGLRenderer.createTextureFromSourcemethod has a new optional boolean parameterforceClampthat will for the clamp wrapping mode even if the texture is a power-of-two. RenderTargetwill 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis a new method that will return a compressed texture format GLenum based on the given format.
New Features
ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.BitmapMaskdestroymethod will now remove the context-lost event handler. - The
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.sceneis a new property that allows the Bitmap Mask to reference the Scene it was created in.- The
DOMElement.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopwill 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
TintandFlipcomponents from theCameraclass. Neither were ever used internally, or during rendering, so it was just confusing having them in the API.
Bug Fixes
Animation.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,TileSpriteandRenderTextureGame 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.compressionAlgorithmis now populated with the compression format used by the texture.Types.Textures.CompressedTextureDatais the new compressed texture configuration object type.TextureManager.addCompressedTextureis a new method that will add a compressed texture, and optionally atlas data into the Texture Manager and return aTextureobject than any Sprite can use.Textures.Parsers.KTXParseris a new parser for the KTX compression container format.Textures.Parsers.PVRParseris a new parser for the PVR compression container format.- The
WebGLRenderer.compressionproperty now holds a more in-depth object containing supported compression formats. - The
WebGLRenderer.createTextureFromSourcemethod now accepts theCompressedTextureDatadata objects and creates WebGL textures from them. WebGLRenderer.getCompressedTexturesis a new method that will populate theWebGLRenderer.compressionobject and return its value. This is called automatically when the renderer boots.WebGLRenderer.getCompressedTextureNameis a new method that will return a compressed texture format GLenum based on the given format.
New Features
ScaleManager.getViewPortis 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.addToDisplayListandremoveFromDisplayListare new methods that allows for you to now add a Layer as a child of another Layer. Fix #5799 (thanks @samme)GameObjects.Video.loadURLhas a new optional 4th parametercrossOrigin. 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.createFromObjectsmethod 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.BitmapMaskdestroymethod will now remove the context-lost event handler. - The
hitAreaparameter of theGameObjects.Zone.setDropZonemethod 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.sceneis a new property that allows the Bitmap Mask to reference the Scene it was created in.- The
DOMElement.preUpdatemethod has been removed. If you overrode this method, please now seepreRenderinstead. DOMElement.preRenderis 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.firewill 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.setEmitterFrameswill 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.stopwill 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.createFromAsepritewould 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.domBehindCanvasproperty as it's never used internally. Fix #5749 (thanks @iamallenchang) dispatchTweenEventwould overwrite one of the callback's parameters. This fix ensures thatTween.setCallbacknow 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.WEBGLwill 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.createFromObjectsmethod 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.snapshotCanvasmethod 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.tileToWorldYmethod incorrectly had the parametertileX. It will worked, but didn't make sense. It is nowtileY(thanks @mayacoda) - The
Tilemap.convertTilemapLayermethod would fail for isometric tilemaps by not setting the physic body alignment properly. It will now callgetBoundscorrectly, allowing for use on non-orthagonal maps. Fix #5764 (thanks @mayacoda) - The
PluginManager.installScenePluginmethod 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.setSizeit 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
ParseTileLayersfunction has been updated so that it no longer breaks when using a Tiled infinite map with empty chunks (thanks @jonnytest1) - The
PutTileAtfunction 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.tileOffsetproperty fixes an issue with drawing isometric tiles when an offset had been defined in the map data (thanks @moJiXiang) - Fixed issue in
Geom.Intersects.GetLineToLinefunction that would fail with colinear lines (thanks @Skel0t) - The
CameraManager.destroyfunction will now remove the Scale ManagerRESIZEevent listener created as part ofboot, where-as before it didn't clean it up, leading to gc issues. Fix #5791 (thanks @liuhongxuan23) - With
roundPixelsset 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_RENDERandPOST_RENDERevents under the Canvas Renderer. Fix #5729 (thanks @ddanushkin) - The Multi Pipeline now uses
highp floatprecision by default, instead ofmediump. 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.getBoundsmethod would take acameraparameter but then not pass it to the methods called internally, thus ignoring it. It now factors the camera into the returned Rectangle. Tilemap.createFromObjectshas 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,IsoBoxWebGLRendererandIsoTriangleWebGLRendererfunctions 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.destroymethod has a newfromSceneparameter, set automatically by Phaser. Fix #5716 (thanks @rexrainbow) - The Game Object
DESTROYevent is now set the newfromSceneboolean 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
FillPathWebGLfunction 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
IsoBoxandIsoTriangleGame Objects that stopped them from rendering correctly. - Added the missing
WebGLPipelineUniformsConfigtype def. Fix #5718 (thanks @PhaserEditor2D)
- JavaScript
Published by photonstorm about 5 years ago
phaser - Phaser v3.55.0
New Features
GameObjects.DOMElement.pointerEventsis a new property that allows you to set thepointerEventsattribute on the DOM Element CSS. This isautoby default and should not be changed unless you know what you're doing.Core.Config.domPointerEventsis a new config property set viadom: { pointerEvents }within the Game Config that allows you to set thepointerEventscss attribute on the DOM Element container.- The
RenderTexture.endDrawmethod has a new optional booleanerasewhich 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
GraphicsPipelinehave now been merged with theMultiPipeline, these includebatchFillRect,batchFillTriangle,batchStrokeTriangle,batchFillPath,batchStrokePathandbatchLine. 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.moveAboveis a new method that will move a Game Object above another in the same Container (thanks @rexrainbow)Container.moveBelowis a new method that will move a Game Object below another in the same Container (thanks @rexrainbow)List.moveAboveis a new method that will move a Game Object above another in the same List (thanks @rexrainbow)List.moveBelowis a new method that will move a Game Object below another in the same List (thanks @rexrainbow)- The
MeasureTextfunction, 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.setUniform1has a new optional boolean parameterskipCheckwhich will force the function to set the values without checking against the previously held ones.WebGLShader.setUniform2has a new optional boolean parameterskipCheckwhich will force the function to set the values without checking against the previously held ones.WebGLShader.setUniform3has a new optional boolean parameterskipCheckwhich will force the function to set the values without checking against the previously held ones.WebGLShader.setUniform4has a new optional boolean parameterskipCheckwhich 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,setMatrix3fvandsetMatrix4fvmethods 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
MeshGame 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.ToXYwill 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.shutdownmethod will now remove thePRE_UPDATEhandler from the ProcessQueue correctly (thanks @samme) - When loading a Video with a config object, it would not get the correct
keyvalue from it (thanks @mattjennings) - The
GameObjectFactory.existingmethod will now acceptLayeras a TypeScript type. Fix #5642 (thanks @michal-bures) - The
Input.Pointer.eventproperty can now be aWheelEventas 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
addToRenderListbefore leaving the render method, fixing an issue with Container Input. Fix #5506 (thanks @vforsh @rexrainbow) - The
Game.postBootcallback was never being invoked due to an incorrect internal property setter. Fix #5689 (thanks @sebastianfast) - The
LightGame 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.Medianis 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.pluginKeyis a new string-based property, set by thePluginManagerthat 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 anyKeyobjects 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
@thistags. Fix #4669. - The
Scenes.Systems.installmethod has been removed. It's no longer required and would throw an error if called. Fix #5580 (thanks @Trissolo) - The
WebAudioSoundManager.onFocusmethod will now test to see if the state of theAudioContextisinterrupted, 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
backgroundColorproperty 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
RGBToStringfunction will no longer return CSS strings with decimal places if the input contained them (thanks @neil-h) - Objects added to a
SpineContainerwere also added to the base Display List, causing them to appear twice. Fix #5599 (thanks @spayton) - When an Animation has
skipMissedFramesset 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 Pluginfactory 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 useimportScripts('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_RENDERis a new event fired after the display list is sorted and before the Scene is rendered (thanks @samme)- You can now set the boolean
preserveDrawingBufferin 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 totrueto retain them. GameObjects.Shape.setDisplaySizeis 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.ParseTilesetshas been updated so it now retains thetypefield information that can be optionally specified within Tiled. This is useful when creating objects from tiles and tile variants (thanks @lackhand)Tilemaps.Parsers.Tiled.ParseWangsetsis 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.glResetis a new boolean property that keeps track of when the GL Context was last reset by the Pipeline Manager. It then redirects calls tobindtorebindinstead to restore the pipeline state.
Display List Updates
GameObject.addToDisplayListis 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.addToUpdateListis 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 itspreUpdatemethod called every game frame.GameObject.removeFromDisplayListis a new method that removes the Game Object from the Display List it is currently on.GameObject.removeFromUpdateListis a new method that removes the Game Object from the Scenes Update List.GameObject.destroywill now call the newremoveFromDisplayListandremoveFromUpdateListmethods.DisplayList.addChildCallbackwill now use the newaddToDisplayListandremoveFromDisplayListGame Object methods.Container.addHandlerwill now use the newaddToDisplayListandremoveFromDisplayListGame Object methods.Layer.addChildCallbackandremoveChildCallbackwill now use the newaddToDisplayListandremoveFromDisplayListGame Object methods.Groupnow listens for theADDED_TO_SCENEandREMOVED_FROM_SCENEmethods and adds and removes itself from the Update List accordingly.Group.addandcreatenow uses the newaddToDisplayListandaddToUpdateListGame Object methods.Group.removenow uses the newremoveFromDisplayListandremoveFromUpdateListGame Object methods.Group.destroyhas a new optional boolean parameterremoveFromScene, 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 thedistfolder. - 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
windowor 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.createAudioContextmethod is no longer private. - The
WebAudioSoundManager.contextproperty is no longer private. - The
WebAudioSoundManager.masterMuteNodeproperty is no longer private. - The
WebAudioSoundManager.masterVolumeNodeproperty is no longer private. - The
WebAudioSoundManager.destinationproperty is no longer private. - The
WebAudioSound.audioBufferproperty is no longer private. - The
WebAudioSound.sourceproperty is no longer private. - The
WebAudioSound.loopSourceproperty is no longer private. - The
WebAudioSound.muteNodeproperty is no longer private. - The
WebAudioSound.volumeNodeproperty is no longer private. - The
WebAudioSound.pannerNodeproperty is no longer private. - The
WebAudioSound.hasEndedproperty is no longer private, but is read only. - The
WebAudioSound.hasLoopedproperty is no longer private, but is read only. - The
WebAudioSoundManager.createAudioContextmethod will now usewebkitAudioContextif defined inwindow(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
fillRectifclearBeforeRenderisfalsein the Game Config. - The
LightsManager.addPointlightmethod now has full JSDocs and theattenuationparameter. LightPipeline.lightsActiveis a new boolean property that keeps track if the Lights Manager in a Scene is active, or not.- The
LightPipelinenow only callsbatchSprite,batchTextureandbatchTextureFrameif 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.getTangentcan now take an output vector to receive the tangent value (thanks @samme)DOMElementCSSRendererno longer sets thepointerEventsstyle attribute toauto. This is the default value anyway and it now means you can override it from your code by setting thepointer-eventsattribute directly. Fix #5470 (thanks @hayatae @endel)SceneManager.loadCompletewill no longer try to unlock the Sound Manager, preventingAudioContext was not allowed to startconsole warnings after each Scene finishes loading.WebGLRenderer.deleteTexturewill now runresetTextures(true)first, incase the requested texture to be deleted is currently bound. Previously, it would delete the texture and then reset them.- If
TextureSource.destroyhas a WebGL Texture it will tell the WebGL Renderer to reset the textures first, before deleting its texture. Cameras.Controls.FixedKeyControl.minZoomis a new configurable property that sets the minimum camera zoom. Default to 0.001 (thanks @samme)Cameras.Controls.FixedKeyControl.maxZoomis a new configurable property that sets the maximum camera zoom. Default to 1000 (thanks @samme)Cameras.Controls.SmoothedKeyControl.minZoomis a new configurable property that sets the minimum camera zoom. Default to 0.001 (thanks @samme)Cameras.Controls.SmoothedKeyControl.maxZoomis a new configurable property that sets the maximum camera zoom. Default to 1000 (thanks @samme)- The
WebGLPipeline.rebindmethod now accepts an optional parametercurrentShader. If provided it will set the current shader to be this after the pipeline reset is complete. - The
PipelineManager.rebindmethod will now flag all pipelines asglReset = true, so they know to fully rebind the next time they are invoked.
Bug Fixes
BlitterWebGLRendererwas calling an out-dated functionsetRenderDepthinstead ofaddToRenderList(thanks Harm)- When a loaded JSON file fails to parse, it's marked
FILE_ERROREDand the Loader continues. Before this change the Loader would stall (thanks @samme) Math.FromPercentsilently assumed theminparameter to be 0. It can now be any value, allowing you to generate percentages betweenminandmaxcorrectly (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)
IsometricWorldToTileXYwas returning a tile incorrectly offset from the given coordinates. It now returns from the expected location (thanks @veleek)DOMElementCSSRendererwill now return early ifsrc.nodedoesn't exist or is null, rather than trying to extract thestyleproperty from it. Fix #5566 (thanks @rattias)- The BitmapMask will now check to see if
rendererexists before trying to hook to its event emitter (thanks @mattjennings) - TileSprite will now check to see if
rendererexists before trying to restore itself during a context loss (thanks @mattjennings) - A Texture will now check to see if
rendererexists 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.PlayAnimationarguments 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 thestartFrameparameter has been replaced withignoreIfPlaying. The function will also only callplayif 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.resizewill nowMath.floorthe scaled width and height as well as ensure they're not <= 0 which causesFramebuffer status: Incomplete Attachmenterrors. Fix #5563 #5478 (thanks @orjandh @venarius)Matter.Components.Sleep.setToSleepandsetAwakewere documented as returningthis, however they didn't return anything. Both nowreturn thiscorrectly. 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
ProcessXwhen 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.destroywould cause a runtime error ifGroup.runChildUpdatehad 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 useimportScripts('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_RENDERis a new event fired after the display list is sorted and before the Scene is rendered (thanks @samme)- You can now set the boolean
preserveDrawingBufferin 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 totrueto retain them. GameObjects.Shape.setDisplaySizeis 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.ParseTilesetshas been updated so it now retains thetypefield information that can be optionally specified within Tiled. This is useful when creating objects from tiles and tile variants (thanks @lackhand)Tilemaps.Parsers.Tiled.ParseWangsetsis 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.glResetis a new boolean property that keeps track of when the GL Context was last reset by the Pipeline Manager. It then redirects calls tobindtorebindinstead to restore the pipeline state.
Display List Updates
GameObject.addToDisplayListis 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.addToUpdateListis 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 itspreUpdatemethod called every game frame.GameObject.removeFromDisplayListis a new method that removes the Game Object from the Display List it is currently on.GameObject.removeFromUpdateListis a new method that removes the Game Object from the Scenes Update List.GameObject.destroywill now call the newremoveFromDisplayListandremoveFromUpdateListmethods.DisplayList.addChildCallbackwill now use the newaddToDisplayListandremoveFromDisplayListGame Object methods.Container.addHandlerwill now use the newaddToDisplayListandremoveFromDisplayListGame Object methods.Layer.addChildCallbackandremoveChildCallbackwill now use the newaddToDisplayListandremoveFromDisplayListGame Object methods.Groupnow listens for theADDED_TO_SCENEandREMOVED_FROM_SCENEmethods and adds and removes itself from the Update List accordingly.Group.addandcreatenow uses the newaddToDisplayListandaddToUpdateListGame Object methods.Group.removenow uses the newremoveFromDisplayListandremoveFromUpdateListGame Object methods.Group.destroyhas a new optional boolean parameterremoveFromScene, 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 thedistfolder. - 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
windowor 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.createAudioContextmethod is no longer private. - The
WebAudioSoundManager.contextproperty is no longer private. - The
WebAudioSoundManager.masterMuteNodeproperty is no longer private. - The
WebAudioSoundManager.masterVolumeNodeproperty is no longer private. - The
WebAudioSoundManager.destinationproperty is no longer private. - The
WebAudioSound.audioBufferproperty is no longer private. - The
WebAudioSound.sourceproperty is no longer private. - The
WebAudioSound.loopSourceproperty is no longer private. - The
WebAudioSound.muteNodeproperty is no longer private. - The
WebAudioSound.volumeNodeproperty is no longer private. - The
WebAudioSound.pannerNodeproperty is no longer private. - The
WebAudioSound.hasEndedproperty is no longer private, but is read only. - The
WebAudioSound.hasLoopedproperty is no longer private, but is read only. - The
WebAudioSoundManager.createAudioContextmethod will now usewebkitAudioContextif defined inwindow(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
fillRectifclearBeforeRenderisfalsein the Game Config. - The
LightsManager.addPointlightmethod now has full JSDocs and theattenuationparameter. LightPipeline.lightsActiveis a new boolean property that keeps track if the Lights Manager in a Scene is active, or not.- The
LightPipelinenow only callsbatchSprite,batchTextureandbatchTextureFrameif 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.getTangentcan now take an output vector to receive the tangent value (thanks @samme)DOMElementCSSRendererno longer sets thepointerEventsstyle attribute toauto. This is the default value anyway and it now means you can override it from your code by setting thepointer-eventsattribute directly. Fix #5470 (thanks @hayatae @endel)SceneManager.loadCompletewill no longer try to unlock the Sound Manager, preventingAudioContext was not allowed to startconsole warnings after each Scene finishes loading.WebGLRenderer.deleteTexturewill now runresetTextures(true)first, incase the requested texture to be deleted is currently bound. Previously, it would delete the texture and then reset them.- If
TextureSource.destroyhas a WebGL Texture it will tell the WebGL Renderer to reset the textures first, before deleting its texture. Cameras.Controls.FixedKeyControl.minZoomis a new configurable property that sets the minimum camera zoom. Default to 0.001 (thanks @samme)Cameras.Controls.FixedKeyControl.maxZoomis a new configurable property that sets the maximum camera zoom. Default to 1000 (thanks @samme)Cameras.Controls.SmoothedKeyControl.minZoomis a new configurable property that sets the minimum camera zoom. Default to 0.001 (thanks @samme)Cameras.Controls.SmoothedKeyControl.maxZoomis a new configurable property that sets the maximum camera zoom. Default to 1000 (thanks @samme)- The
WebGLPipeline.rebindmethod now accepts an optional parametercurrentShader. If provided it will set the current shader to be this after the pipeline reset is complete. - The
PipelineManager.rebindmethod will now flag all pipelines asglReset = true, so they know to fully rebind the next time they are invoked.
Bug Fixes
BlitterWebGLRendererwas calling an out-dated functionsetRenderDepthinstead ofaddToRenderList(thanks Harm)- When a loaded JSON file fails to parse, it's marked
FILE_ERROREDand the Loader continues. Before this change the Loader would stall (thanks @samme) Math.FromPercentsilently assumed theminparameter to be 0. It can now be any value, allowing you to generate percentages betweenminandmaxcorrectly (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)
IsometricWorldToTileXYwas returning a tile incorrectly offset from the given coordinates. It now returns from the expected location (thanks @veleek)DOMElementCSSRendererwill now return early ifsrc.nodedoesn't exist or is null, rather than trying to extract thestyleproperty from it. Fix #5566 (thanks @rattias)- The BitmapMask will now check to see if
rendererexists before trying to hook to its event emitter (thanks @mattjennings) - TileSprite will now check to see if
rendererexists before trying to restore itself during a context loss (thanks @mattjennings) - A Texture will now check to see if
rendererexists 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.PlayAnimationarguments 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 thestartFrameparameter has been replaced withignoreIfPlaying. The function will also only callplayif 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.resizewill nowMath.floorthe scaled width and height as well as ensure they're not <= 0 which causesFramebuffer status: Incomplete Attachmenterrors. Fix #5563 #5478 (thanks @orjandh @venarius)Matter.Components.Sleep.setToSleepandsetAwakewere documented as returningthis, however they didn't return anything. Both nowreturn thiscorrectly. 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
ProcessXwhen 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.destroywould cause a runtime error ifGroup.runChildUpdatehad 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
getPostPipelinemethod 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.renderListis a new array that is populated with all Game Objects that the camera has rendered in the current frame. It is automatically cleared duringCamera.preUpdateand 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.addToRenderListis a new method that will add the given Game Object to the Cameras current render list.- The
InputPlugin.sortGameObjectsmethod now uses the new Camera render list to work out the display index depths. - The
InputPlugin.sortDropZonesmethod is a new method, based on the oldsortGameObjectsmethod 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.destroynow checks to see ifpannerNodeexists before disabling it, preventing an error in Safari (thanks @jdcook)- Fixed the cause of
Uncaught TypeError: Cannot read property 'getIndex' of nullby 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.weightedRandomizehas changed so that the parameterweightedIndexesis 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
GenerateVertsfunction was returning an object with the propertyvertsinstead ofverticesas expected by theMesh.addVerticesmethod. It now returns the correct name (thanks @lackhand) AtlasJSONFilewill now callFile.pendingDestroy, clearing up the resources it used during load and emitting a missingFILE_COMPLETEevent. Fix #5495 (thanks @mikuso)AtlasJSONFile,AtlasXMLFile,BitmapFontFileandUnityAtlasFilewill now callFile.pendingDestroy, clearing up the resources it used during load and emiting a missingFILE_COMPLETEevent. 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
__BASEframe 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.isTextureCleanis 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.removePostPipelinewould 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.destroywill now calldestroyon all of its children as well.- The
LayerGame Object has been given all of the missing properties and methods from Game Object to make the class shapes identical. This includes the propertiesparentContainer,tabIndex,inputandbody. You cannot set any of these properties, they are ignored by the Layer itself. It also includes the methods:setInteractive,disableInteractiveandremoveInteractive. A Layer cannot be enabled for input or have a physics body. Fix #5459 (thanks @PhaserEditor2D) Layer.getIndexListis 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
keyupevent 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 nullto 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.destroywill now emit theDESTROYevent 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.pipelinesis no longer a plain object containing pipeline instances. It's now an instance of thePipelineManagerclass. This instance is created during the init and boot phase of the renderer.- The
WebGLRenderer.currentPipelineproperty no longer exists, instead usePipelineManager.current. - The
WebGLRenderer.previousPipelineproperty no longer exists, instead usePipelineManager.previous. - The
WebGLRenderer.hasPipelinemethod no longer exists, instead usePipelineManager.has. - The
WebGLRenderer.getPipelinemethod no longer exists, instead usePipelineManager.get. - The
WebGLRenderer.removePipelinemethod no longer exists, instead usePipelineManager.remove. - The
WebGLRenderer.addPipelinemethod no longer exists, instead usePipelineManager.add. - The
WebGLRenderer.setPipelinemethod no longer exists, instead usePipelineManager.set. - The
WebGLRenderer.rebindPipelinemethod no longer exists, instead usePipelineManager.rebind. - The
WebGLRenderer.clearPipelinemethod no longer exists, instead usePipelineManager.clear.
The Pipeline Manager also offers the following new features:
- The
PipelineManager.resizemethod automatically handles resize events across all pipelines. - The
PipelineManager.preRendermethod calls the pre-render method of all pipelines. - The
PipelineManager.rendermethod calls the render method of all pipelines. - The
PipelineManager.postRendermethod calls the post-render method of all pipelines. - The
PipelineManager.setMultimethod automatically binds the Multi Texture Pipeline, Phasers default. - The
PipelineManager.clearmethod will clear the pipeline, store it inpreviousand free the renderer. - The
PipelineManager.rebindmethod will reset the rendering context and restore thepreviouspipeline, if set. - The
PipelineManager.copyFramemethod will copy asourceRender Target to thetargetRender Target, optionally setting the brightness of the copy. - The
PipelineManager.blitFramemethod will copy asourceRender Target to thetargetRender Target. UnlikecopyFrameno resizing takes place and you can optionally set the brightness and erase mode of the copy. - The
PipelineManager.copyFrameRectmethod binds thesourceRender Target and then copies a section of it to thetargetusinggl.copyTexSubImage2Drather than a shader, making it much faster if you don't need blending or preserving alpha details. - The
PipelineManager.copyToGamemethod pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws thesourceRender Target to it. Use when you need to render the final result to the game canvas. - The
PipelineManager.drawFramemethod will copy asourceRender Target, optionally to atargetRender Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy. - The
PipelineManager.blendFramesmethod draws thesource1andsource2Render Targets to thetargetRender Target using a linear blend effect, which is controlled by thestrengthparameter. - The
PipelineManager.blendFramesAdditivemethod draws thesource1andsource2Render Targets to thetargetRender Target using an additive blend effect, which is controlled by thestrengthparameter. - The
PipelineManager.clearFramemethod 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_PIPELINEfor the Bitmap Mask Pipeline.Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINEfor the Light 2D Pipeline.Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINEfor the Single Pipeline.Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINEfor the Multi Pipeline.Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINEfor the Rope Pipeline.Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINEfor the Point Light Pipeline.Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINEfor the Post FX Pipeline.Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINEfor 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.gameObjectproperty is a reference to the Game Object that owns the Post Pipeline, if any. - The
PostFXPipeline.colorMatrixproperty is a Color Matrix instance used by the draw shader. - The
PostFXPipeline.fullFrame1property is a reference to thefullFrame1Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.fullFrame2property is a reference to thefullFrame2Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.halfFrame1property is a reference to thehalfFrame1Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.halfFrame2property is a reference to thehalfFrame2Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.copyFramemethod will copy asourceRender Target to thetargetRender Target, optionally setting the brightness of the copy. - The
PostFXPipeline.blitFramemethod will copy asourceRender Target to thetargetRender Target. UnlikecopyFrameno resizing takes place and you can optionally set the brightness and erase mode of the copy. - The
PostFXPipeline.copyFrameRectmethod binds thesourceRender Target and then copies a section of it to thetargetusinggl.copyTexSubImage2Drather than a shader, making it much faster if you don't need blending or preserving alpha details. - The
PostFXPipeline.copyToGamemethod pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws thesourceRender Target to it. Use when you need to render the final result to the game canvas. - The
PostFXPipeline.drawFramemethod will copy asourceRender Target, optionally to atargetRender Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy. - The
PostFXPipeline.blendFramesmethod draws thesource1andsource2Render Targets to thetargetRender Target using a linear blend effect, which is controlled by thestrengthparameter. - The
PostFXPipeline.blendFramesAdditivemethod draws thesource1andsource2Render Targets to thetargetRender Target using an additive blend effect, which is controlled by thestrengthparameter. - The
PostFXPipeline.clearFramemethod clears the given Render Target. - The
PostFXPipeline.bindAndDrawmethod binds this pipeline and draws thesourceRender Target to thetargetRender 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:
TextureTintPipelineis now called theMultiPipeline.TextureTintStripPipelineis now called theRopePipeline.ForwardDiffuseLightPipelineis now called theLightPipeline.
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.fragis now calledLight.frag.TextureTint.fragis now calledMulti.frag.TextureTint.vertis now calledMulti.vert.
WebGL Pipelines Updates
Further pipeline changes are as follows:
- None of the shaders or pipelines use the
uViewMatrixanduModelMatrixuniforms 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.WebGLPipelineConfigis a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.Types.Renderer.WebGL.WebGLPipelineAttributesConfigis 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
rendererproperty automatically, so it's no longer required in the config. - All pipelines will now work out the
glproperty automatically, so it's no longer required in the config. - All pipelines will now extract the
nameproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexCapacityproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexSizeproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexDataproperty from the config, allowing you to set it externally. - All pipelines will now extract the
attributesproperty from the config, allowing you to set it externally. - All pipelines will now extract the
topologyproperty from the config, allowing you to set it externally. - The
WebGLPipeline.shouldFlushmethod now accepts an optional parameteramount. If given, it will returntrueif 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
RopePipelinenow extendsMultiPipelineand just changes the topology, vastly reducing the file size. - The
WebGLPipeline.flushLockedproperty 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.manageris a new property that is a reference to the WebGL Pipeline Manager.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLPipeline.forceZerois a new boolean property that sets if the pipeline should force the use of texture zero.WebGLPipeline.hasBootedis a new boolean property that is set once the pipeline has finished setting itself up and has booted.WebGLPipeline.isPostFXis a new boolean property that is only set by Post FX Pipelines to help identify them.WebGLPipeline.renderTargetsis a new property that holds an array of WebGL Render Targets belonging to the pipeline.WebGLPipeline.currentRenderTargetis a new property that holds a reference to the currently bound Render Target.WebGLPipeline.shadersis a new property that holds an array of all WebGLShader instances that belong to the pipeline.WebGLPipeline.currentShaderis a new property that holds a reference to the currently active shader within the pipeline.WebGLPipeline.configis a new property that holds the pipeline configuration object used to create it.WebGLPipeline.projectionMatrixis a new property that holds a Matrix4 used as the projection matrix for the pipeline.WebGLPipeline.setProjectionMatrixis a new method that allows you to set the ortho projection matrix of the pipeline.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLPipeline.setShaderis a new method that allows you to set the currently active shader within the pipeline.WebGLPipeline.getShaderByNameis a new method that allows you to get a shader from the pipeline based on its name.WebGLPipeline.setShadersFromConfigis 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.setGameObjectis a new method that custom pipelines can use in order to perform pre-batch tasks for the given Game Object.WebGLPipeline.setVertexBufferis 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.preBatchis 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.postBatchis 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.unbindis a new method that unbinds the current Render Target, if one is set.WebGLPipeline.batchVertis a new method that adds a single vertex to the vertex buffer and increments the count by 1.WebGLPipeline.batchQuadis 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.batchTriis 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.drawFillRectis a new method that pushes a filled rectangle into the vertex batch.WebGLPipeline.setTexture2Dis a new method that sets the texture to be bound to the next available texture unit.WebGLPipeline.bindTextureis a new method that immediately activates the given WebGL Texture and binds it to the requested slot.WebGLPipeline.bindRenderTargetis a new method that binds the given Render Target to a given texture slot.WebGLPipeline.setTimeis 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.onBootis a new hook you can override in your own pipelines that is called when the pipeline has booted.WebGLPipeline.onResizeis a new hook you can override in your own pipelines that is called when the pipeline is resized.WebGLPipeline.onDrawis a new hook you can override in your own pipelines that is called by Post FX Pipelines every timepostBatchis invoked.WebGLPipeline.onActiveis 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.onBindis 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.onRebindis 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.onBatchis 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.onPreBatchis 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.onPostBatchis 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.onPreRenderis a new hook you can override in your own pipelines that is called once, per frame, right before anything has been rendered.WebGLPipeline.onRenderis 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.onPostRenderis 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.onBeforeFlushis a new hook you can override in your own pipelines that is called immediately before thegl.bufferDataandgl.drawArrayscalls are made, so you can perform any final pre-render modifications.WebGLPipeline.onAfterFlushis a new hook you can override in your own pipelines that is called aftergl.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_FLUSHevent is dispatched by a WebGL Pipeline right after it has issued adrawArrayscommand. - The
WebGL.Pipelines.Events.BEFORE_FLUSHevent is dispatched by a WebGL Pipeline right before it is about to flush. - The
WebGL.Pipelines.Events.BINDevent is dispatched by a WebGL Pipeline when it is bound by the Pipeline Manager. - The
WebGL.Pipelines.Events.BOOTevent is dispatched by a WebGL Pipeline when it has finished booting. - The
WebGL.Pipelines.Events.DESTROYevent is dispatched by a WebGL Pipeline when it begins its destruction process. - The
WebGL.Pipelines.Events.REBINDevent is dispatched by a WebGL Pipeline when the Pipeline Manager resets and rebinds it. - The
WebGL.Pipelines.Events.RESIZEevent 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.set1fwill set a 1f uniform based on the given name.WebGLPipeline.set2fwill set a 2f uniform based on the given name.WebGLPipeline.set3fwill set a 3f uniform based on the given name.WebGLPipeline.set4fwill set a 4f uniform based on the given name.WebGLPipeline.set1fvwill set a 1fv uniform based on the given name.WebGLPipeline.set2fvwill set a 2fv uniform based on the given name.WebGLPipeline.set3fvwill set a 3fv uniform based on the given name.WebGLPipeline.set4fvwill set a 4fv uniform based on the given name.WebGLPipeline.set1ivwill set a 1iv uniform based on the given name.WebGLPipeline.set2ivwill set a 2iv uniform based on the given name.WebGLPipeline.set3ivwill set a 3iv uniform based on the given name.WebGLPipeline.set4ivwill set a 4iv uniform based on the given name.WebGLPipeline.set1iwill set a 1i uniform based on the given name.WebGLPipeline.set2iwill set a 2i uniform based on the given name.WebGLPipeline.set3iwill set a 3i uniform based on the given name.WebGLPipeline.set4iwill set a 4i uniform based on the given name.WebGLPipeline.setMatrix2fvwill set a matrix 2fv uniform based on the given name.WebGLPipeline.setMatrix3fvwill set a matrix 3fv uniform based on the given name.WebGLPipeline.setMatrix4fvwill 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.setFloat1has been removed. Please useset1finstead.WebGLPipeline.setFloat2has been removed. Please useset2finstead.WebGLPipeline.setFloat3has been removed. Please useset3finstead.WebGLPipeline.setFloat4has been removed. Please useset4finstead.WebGLPipeline.setFloat1vhas been removed. Please useset1fvinstead.WebGLPipeline.setFloat2vhas been removed. Please useset2fvinstead.WebGLPipeline.setFloat3vhas been removed. Please useset3fvinstead.WebGLPipeline.setFloat4vhas been removed. Please useset4fvinstead.WebGLPipeline.setInt1has been removed. Please useset1iinstead.WebGLPipeline.setInt2has been removed. Please useset2iinstead.WebGLPipeline.setInt3has been removed. Please useset3iinstead.WebGLPipeline.setInt4has been removed. Please useset4iinstead.WebGLPipeline.setMatrix1has been removed. Please usesetMatrix2fvinstead.WebGLPipeline.setMatrix2has been removed. Please usesetMatrix3fvinstead.WebGLPipeline.setMatrix3has been removed. Please usesetMatrix4fvinstead.
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.
hasPostPipelineis a new boolean property that indicates if the Game Object has one, or more post pipelines set.postPipelinesis a new property that contains an array of Post Pipelines owned by the Game Object.pipelineDatais a new object object to store pipeline specific data in.- The
setPipelinemethod has been updated with 2 new parameters:pipelineDataandcopyData. These allow you to populate the pipeline data object during setting. - You can now pass a pipeline instance to the
setPipelinemethod, as well as a string. setPostPipelineis 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.setPipelineDatais a new method that allows you to set a key/value pair into the pipeline data object in a chainable way.getPostPipelineis a new method that will return a Post Pipeline instance from the Game Object based on the given string, function or instance.- The
resetPipelinemethod has two new parametersresetPostPipelineandresetData, both false by default, that will reset the Post Pipelines and pipeline data accordingly. resetPostPipelineis a new method that will specifically reset just the Post Pipelines, and optionally the pipeline data.removePostPipelineis 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.colorMatrixproperty is an instance of a ColorMatrix class, used by the draw shader. - The
UtilityPipeline.copyShaderproperty is a reference to the Copy Shader. - The
UtilityPipeline.addShaderproperty is a reference to the additive blend shader. - The
UtilityPipeline.linearShaderproperty is a reference to the linear blend shader. - The
UtilityPipeline.colorMatrixShaderproperty is a reference to the color matrix (draw) shader. - The
UtilityPipeline.fullFrame1property is a full sized Render Target that can be used as a temporary buffer during post processing calls. - The
UtilityPipeline.fullFrame2property is a full sized Render Target that can be used as a temporary buffer during post processing calls. - The
UtilityPipeline.halfFrame1property 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.halfFrame2property 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.copyFramemethod will copy asourceRender Target to thetargetRender Target, optionally setting the brightness of the copy. - The
UtilityPipeline.blitFramemethod will copy asourceRender Target to thetargetRender Target. UnlikecopyFrameno resizing takes place and you can optionally set the brightness and erase mode of the copy. - The
UtilityPipeline.copyFrameRectmethod binds thesourceRender Target and then copies a section of it to thetargetusinggl.copyTexSubImage2Drather than a shader, making it much faster if you don't need blending or preserving alpha details. - The
UtilityPipeline.copyToGamemethod pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws thesourceRender Target to it. Use when you need to render the final result to the game canvas. - The
UtilityPipeline.drawFramemethod will copy asourceRender Target, optionally to atargetRender Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy. - The
UtilityPipeline.blendFramesmethod draws thesource1andsource2Render Targets to thetargetRender Target using a linear blend effect, which is controlled by thestrengthparameter. - The
UtilityPipeline.blendFramesAdditivemethod draws thesource1andsource2Render Targets to thetargetRender Target using an additive blend effect, which is controlled by thestrengthparameter. - The
UtilityPipeline.clearFramemethod clears the given Render Target. - The
UtilityPipeline.setUVsmethod allows you to set the UV values for the 6 vertices that make-up the quad belonging to the Utility Pipeline. - The
UtilityPipeline.setTargetUVsmethod 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.flipXmethod horizontally flips the UV coordinates of the quad used by the shaders. - The
UtilityPipeline.flipYmethod vertically flips the UV coordinates of the quad used by the shaders. - The
UtilityPipeline.resetUVsmethod 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis 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.batchPointLightmethod 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.batchLightVertmethod is a special internal method, used bybatchPointLightthat 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 (
inPositionandinColor), 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
calcMatrixproperty has been added, which Shape Game Objects use to maintain transform state during rendering. - The Graphics Pipeline no longer makes use of
tintEffector 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.setTexturehas 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.renderWebGLnow uses the standardGetCalcMatrixfunction, 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.pipelineproperty is a reference to the WebGL Pipeline that owns the WebGLShader instance. - The
WebGLShader.nameproperty is the name of the shader. - The
WebGLShader.rendererproperty is a reference to the WebGL Renderer. - The
WebGLShader.glproperty is a reference to the WebGL Rendering Context. - The
WebGLShader.programproperty is the WebGL Program created from the vertex and fragment shaders. - The
WebGLShader.attributesproperty is an array of objects that describe the vertex attributes of the shader. - The
WebGLShader.vertexComponentCountproperty is the total amount of vertex attribute components of 32-bit length. - The
WebGLShader.vertexSizeproperty is the size, in bytes, of a single vertex. - The
WebGLShader.uniformsproperty is an object that is automatically populated with all active uniforms in the shader. - The
WebGLShader.createAttributesmethod takes the vertex attributes config and parses it, creating the shader attributes. This is called automatically. - The
WebGLShader.bindmethod sets the program the shader uses as being active. Called automatically when the parent pipeline needs this shader. - The
WebGLShader.rebindmethod sets the program the shader uses as being active and resets all of the vertex attribute pointers. - The
WebGLShader.setAttribPointersmethod sets the vertex attribute pointers. Called automatically duringbind. - The
WebGLShader.createUniformsmethod populates theuniformsobject with details about all active uniforms. - The
WebGLShader.hasUniformmethod returns a boolean if the given uniform exists. - The
WebGLShader.resetUniformmethod resets the cached value for the given uniform. - The
WebGLShader.setUniform1method is an internal method used for setting a single value uniform on the shader. - The
WebGLShader.setUniform2method is an internal method used for setting a double value uniform on the shader. - The
WebGLShader.setUniform3method is an internal method used for setting a triple value uniform on the shader. - The
WebGLShader.setUniform4method is an internal method used for setting a quadruple value uniform on the shader. - The
WebGLShader.set1fmethod sets a 1f uniform based on the given name. - The
WebGLShader.set2fmethod sets a 2f uniform based on the given name. - The
WebGLShader.set3fmethod sets a 3f uniform based on the given name. - The
WebGLShader.set4fmethod sets a 4f uniform based on the given name. - The
WebGLShader.set1fvmethod sets a 1fv uniform based on the given name. - The
WebGLShader.set2fvmethod sets a 2fv uniform based on the given name. - The
WebGLShader.set3fvmethod sets a 3fv uniform based on the given name. - The
WebGLShader.set4fvmethod sets a 4fv uniform based on the given name. - The
WebGLShader.set1ivmethod sets a 1iv uniform based on the given name. - The
WebGLShader.set2ivmethod sets a 2iv uniform based on the given name. - The
WebGLShader.set3ivmethod sets a 3iv uniform based on the given name. - The
WebGLShader.set4ivmethod sets a 4iv uniform based on the given name. - The
WebGLShader.set1imethod sets a 1i uniform based on the given name. - The
WebGLShader.set2imethod sets a 2i uniform based on the given name. - The
WebGLShader.set3imethod sets a 3i uniform based on the given name. - The
WebGLShader.set4imethod sets a 4i uniform based on the given name. - The
WebGLShader.setMatrix2fvmethod sets a matrix 2fv uniform based on the given name. - The
WebGLShader.setMatrix3fvmethod sets a matrix 3fv uniform based on the given name. - The
WebGLShader.setMatrix4fvmethod sets a matrix 4fv uniform based on the given name. - The
WebGLShader.destroymethod 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.rendererproperty is a reference to the WebGL Renderer. - The
RenderTarget.framebufferproperty is the WebGLFramebuffer belonging to the Render Target. - The
RenderTarget.textureproperty is a WebGLTexture belonging to the Render Target and bound to the framebuffer. - The
RenderTarget.widthproperty is the width of the Render Target. - The
RenderTarget.heightproperty is the height of the Render Target. - The
RenderTarget.scaleproperty is the scale of the Render Target, applied to the dimensions during resize. - The
RenderTarget.minFilterproperty is the min filter of the texture. - The
RenderTarget.autoClearproperty is a boolean that controls if the Render Target is automatically cleared when bound. - The
RenderTarget.autoResizeproperty is a boolean that controls if the Render Target is automatically resized if the WebGLRenderer resizes. - The
RenderTarget.setAutoResizemethod lets you set the auto resize of the Render Target. - The
RenderTarget.resizemethod lets you resize the Render Target. - The
RenderTarget.bindmethod sets the Render Target as being the active fbo in the renderer and optionally clears and adjusts the viewport. - The
RenderTarget.adjustViewportmethod sets the viewport to match the Render Target dimensions. - The
RenderTarget.clearmethod disables the scissors, clears the Render Target and resets the scissors again. - The
RenderTarget.unbindmethod flushes the renderer and pops the Render Target framebuffer from the stack. - The
RenderTarget.destroymethod 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture that was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.WebGLRenderer.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLRenderer.unbindTexturesis a new method that will activate and then null bind all WebGL textures.Renderer.WebGL.Utils.parseFragmentShaderMaxTexturesis 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.getComponentCountfunction has been removed as this is no longer required internally.
WebGLRenderer New Features, Updates and API Changes
WebGLRenderer.instancedArraysExtensionis a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.WebGLRenderer.vaoExtensionis a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.WebGLRenderer.resetProgramis a new method that will rebind the current program, without flushing or changing any properties.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.WebGLRenderer.finalTypeis a new boolean property that signifies if the current Game Object being rendered is the final one in the list.- The
WebGLRenderer.updateCanvasTexturemethod will now setgl.UNPACK_PREMULTIPLY_ALPHA_WEBGLto 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.previousPipelineis a new property that is set during a call toclearPipelineand used during calls torebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.- The
WebGLRenderer.rebindPipelinemethod has been changed slightly. Previously, you had to specify thepipelineInstance, but this is now optional. If you don't, it will use the newpreviousPipelineproperty instead. If not set, or none given, it will now return without throwing gl errors as well. WebGLRenderer.defaultScissoris a new property that holds the default scissor dimensions for the renderer. This is modified duringresizeand avoids continuous array generation in thepreRenderloop.- The
WebGLRenderer.nativeTexturesarray has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in theTextureSourceobjects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy. - The
WebGLRenderer.deleteTexturemethod has a new optional boolean parameterresetwhich allows you to control if theWebGLRenderer.resetTexturesmethod is called, or not, after the texture is deleted. - The
WebGLRenderer.getMaxTexturesmethod has been removed. This is no longer needed as you can use theWebGLRenderer.maxTexturesproperty instead. - The
WebGLRenderer.setProgrammethod now returns a boolean.trueif the program was set, otherwisefalse. WebGLRenderer.setFloat1has been removed. UseWebGLPipeline.set1forWebGLShader.set1finstead.WebGLRenderer.setFloat2has been removed. UseWebGLPipeline.set2forWebGLShader.set2finstead.WebGLRenderer.setFloat3has been removed. UseWebGLPipeline.set3forWebGLShader.set3finstead.WebGLRenderer.setFloat4has been removed. UseWebGLPipeline.set4forWebGLShader.set4finstead.WebGLRenderer.setFloat1vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set1fvinstead.WebGLRenderer.setFloat2vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set2fvinstead.WebGLRenderer.setFloat3vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set3fvinstead.WebGLRenderer.setFloat4vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set4fvinstead.WebGLRenderer.setInt1has been removed. UseWebGLPipeline.set1fiorWebGLShader.set1iinstead.WebGLRenderer.setInt2has been removed. UseWebGLPipeline.set1fiorWebGLShader.set2iinstead.WebGLRenderer.setInt3has been removed. UseWebGLPipeline.set1fiorWebGLShader.set3iinstead.WebGLRenderer.setInt4has been removed. UseWebGLPipeline.set1fiorWebGLShader.set4iinstead.WebGLRenderer.setMatrix2has been removed. UseWebGLPipeline.setMatrix2fvorWebGLShader.setMatrix2fvinstead.WebGLRenderer.setMatrix3has been removed. UseWebGLPipeline.setMatrix3fvorWebGLShader.setMatrix3fvinstead.WebGLRenderer.setMatrix4has been removed. UseWebGLPipeline.setMatrix4fvorWebGLShader.setMatrix4fvinstead.- The
WebGLRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead. WebGLRenderer.fboStackis a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.WebGLRenderer.pushFramebufferis 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 ofsetFramebuffer. Remember to callpopFramebufferafter using it.WebGLRenderer.popFramebufferis a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.WebGLRenderer.setFramebufferhas a new optional boolean parameterresetTextureswhich will reset the WebGL Textures, if set totrue(which is the default).WebGLRenderer.isBootedis a new boolean property that lets you know if the renderer has fully finished booting.- The
WebGLRenderernow extends the Event Emitter, allowing you to listen to renderer specific events. WebGLRenderer.defaultCamerahas been removed as it's not used anywhere internally any longer.- The
WebGLRenderer.setVertexBuffermethod has been removed along with theWebGLRenderer.currentVertexBufferproperty. This is now set directly by the WebGL Pipeline, as needed. - The
WebGLRenderer.setIndexBuffermethod has been removed along with theWebGLRenderer.currentIndexBufferproperty. This is now set directly by the WebGL Pipeline, as needed. WebGLRenderer.resetScissoris a new method that will reset the gl scissor state to be the current scissor, if there is one, without modifying the stack.WebGLRenderer.resetViewportis a new method that will reset the gl viewport to the current renderer dimensions.WebGLRenderer.renderTargetis a new property that contains a Render Target that is bound to the renderer and kept resized to match it.WebGLRenderer.beginCaptureis a new method that will bind the renderers Render Target, so everything drawn is redirected to it.WebGLRenderer.endCaptureis a new method that will unbind the renderers Render Target and return it, preventing anything else from being drawn to it.WebGLRenderer.setProjectionMatrixis a new method that sets the global renderer projection matrix to the given dimensions.WebGLRenderer.resetProjectionMatrixis a new method that resets the renderer projection matrix back to match the renderer size.WebGLRenderer.getAspectRatiois 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:
projIdentityhas been removed.projPersphas been removed.modelRotateXhas been removed.modelRotateYhas been removed.modelRotateZhas been removed.viewLoadhas been removed.viewRotateXhas been removed.viewRotateYhas been removed.viewRotateZhas been removed.viewScalehas been removed.viewTranslatehas been removed.modelIdentityhas been removed.modelScalehas been removed.modelTranslatehas been removed.viewIdentityhas been removed.viewLoad2Dhas been removed.projOrthohas been removed.
WebGL and Canvas Renderer Events
Phaser.Renderer.Eventsis a new namespace for events emitted by the Canvas and WebGL Renderers.Renderer.Events.PRE_RENDERis a new event dispatched by the Phaser Renderer. This happens right at the start of the render process.Renderer.Events.RENDERis 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_RENDERis a new event dispatched by the Phaser Renderer. This happens right at the end of the render process.Renderer.Events.RESIZEis a new event dispatched by the Phaser Renderer whenever it is resized.
Canvas Renderer Updates
CanvasRenderer.isBootedis a new boolean property that lets you know if the renderer has fully finished booting.- The
CanvasRenderernow 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.renderToTextureproperty has been removed. Effects are now handled via pipelines. - The
Camera.renderToGameproperty has been removed. Effects are now handled via pipelines. - The
Camera.canvasproperty has been removed. Textures are handled by pipelines. - The
Camera.contextproperty has been removed. Textures are handled by pipelines. - The
Camera.glTextureproperty has been removed. GL Textures are handled by pipelines. - The
Camera.framebufferproperty has been removed. GL Framebuffers are handled by pipelines. - The
Camera.setRenderToTexturemethod has been removed. Effects are now handled via pipelines. - The
Camera.clearRenderToTexturemethod 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.zoomXis a new property that allows you to specifically set the horizontal zoom factor of a Camera.Camera.zoomYis a new property that allows you to specifically set the vertical zoom factor of a Camera.- The
Camera.setZoommethod now allows you to pass two parameters:xandy, to control thezoomXandzoomYvalues accordingly. - The
Camera.zoomproperty now returns an average of thezoomXandzoomYproperties. Cameras.Scene2D.Events.FOLLOW_UPDATEis 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
roundPixelsset it will now round the internal scroll factors andworldViewduring thepreRenderstep. 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.
SpineContaineris a new Game Object available viathis.add.spineContainerto 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.runtimeswhich will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo intoplugins/spine/in order for this to work and then runnpm 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-zeroerror 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.setAnimationmethod will now use thetrackIndexparameter ifignoreIfPlayingis set and run the check against this track index. Fix #4842 (thanks @vinerz) - The
SpineFilewill 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
destroymethod 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.gameDestroyis a new method that is called if the Game instance emits adestroyevent. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.SpineFilewill 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)SpineFilenow 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.willRenderis no longer hard-coded to returntrue. 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.renderTargetis a new property that contains aRenderTargetinstance, which is used for all drawing.- The
RenderTexture.framebufferproperty has been removed. You can now access this viaRenderTexture.renderTarget.framebuffer. - The
RenderTexture.glTextureproperty has been removed. You can now access this viaRenderTexture.renderTarget.texture. - The
RenderTexture.glproperty has been removed.
Render Textures have the following new features:
RenderTexture.beginDrawis a new method that allows you to create a batched draw to the Render Texture. Use this method to begin the batch.RenderTexture.batchDrawis 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 withbeginDraw. 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.batchDrawFrameis 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 withbeginDraw. 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.endDrawis 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
Groupto aRenderTexture. 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 fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.RenderTexture.fillwould 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.erasehas 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.colorproperty is an instance of the Color object that controls the color value of the light. - The
PointLight.intensityproperty sets the intensity of the light. The colors of the light are multiplied by this value during rendering. - The
PointLight.attenuationproperty sets the attenuation of the light, which is the force with which the light falls off from its center. - The
PointLight.radiusproperty 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.Meshis 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.Vertexis a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.Geom.Mesh.Faceis a new class that consists of references to the threeVertexinstances that construct a single Face in a Mesh and provides methods for manipulating them.Geom.Mesh.GenerateVertsis a new function that will return an array ofVertexandFaceobjects 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.GenerateGridVertsis a new function that will generate a series ofVertexobjects in a grid format, based on the givenGenerateGridConfigconfig 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.GenerateObjVertsis a new function that will generate a series ofVertexobjects 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.ParseObjis a new function that will parse a triangulated Wavefront OBJ file into model data into a format that theGenerateObjVertsfunction can consume.Geom.Mesh.ParseObjMaterialis 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.RotateFaceis a new function that will rotate a Face by a given amount, based on an optional center of rotation.Loader.OBJFileis 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
MeshFactorysignatures have changed toscene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first.indiciesis a new parameter that allows you to provide indexed vertex data to create the Mesh from, where theindiciesarray holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. Theindiciesarray is optional. If your data is not indexed, then simply passnullor an empty array for this parameter. - The
MeshGame 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.addVerticesis 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.addVerticesFromObjis a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the newOBJFilewith athis.load.objcall, 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.hideCCWis 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.modelPositionis a new Vector3 property that allows you to translate the position of all vertices in the Mesh.Mesh.modelRotationis a new Vector3 property that allows you to rotate all vertices in the Mesh.Mesh.modelScaleis a new Vector3 property that allows you to scale all vertices in the Mesh.Mesh.panXis a new function that will translate the view position of the Mesh on the x axis.Mesh.panYis a new function that will translate the view position of the Mesh on the y axis.Mesh.panZis a new function that will translate the view position of the Mesh on the z axis.Mesh.setPerspectiveis a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.Mesh.setOrthois a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.Mesh.clearis a new method that will destroy all Faces and Vertices and clear the Mesh.Mesh.depthSortis a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.Mesh.addVertexis a new method that allows you to add a new single Vertex into the Mesh.Mesh.addFaceis a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.Mesh.getFaceCountnew is a new method that will return the total number of Faces in the Mesh.Mesh.getVertexCountnew is a new method that will return the total number of Vertices in the Mesh.Mesh.getFacenew is a new method that will return a Face instance from the Mesh based on the given index.Mesh.getFaceAtnew 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.verticesis now an array ofGameObject.Vertexinstances, not a Float32Array.Mesh.facesis a new array ofGameObject.Faceinstances, which is populated during a call to methods likeaddVerticesoraddModel.Mesh.totalRenderedis a new property that holds the total number of Faces that were rendered in the previous frame.Mesh.setDebugis 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
BringToTopto 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
MeshGame Object now extends theSingleAlphacomponent 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 standardsetAlphamethods. 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
colorsparameter in the constructor, factory method andaddVerticesmethod. 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
alphasparameter in the constructor, factory method andaddVerticesmethod. If a number, instead of an array, it will be used as the alpha for all vertices created. Mesh.debugGraphicis a new property that holds the debug Graphics instance reference.Mesh.debugCallbackis a new property that holds the debug render callback.Mesh.renderDebugVertsis a new method that acts as the default render callback forsetDebugif none is provided.Mesh.preDestroyis a new method that will clean-up the Mesh arrays and debug references on destruction.Mesh.isDirtyis a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically inpreUpdateto avoid generating lots of math when nothing has changed.- The
Mesh.uvarray has been removed. All UV data is now bound in the Vertex instances. - The
Mesh.colorsarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.alphasarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.tintFillproperty is now abooleanand defaults tofalse.
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.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycoordinates. The character data includes the code, position, dimensions, and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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
setMaxWidthonDynamicBitmapText, 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
Animationclass no longer extendsEventEmitter, 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_KEYevents have been removed. Instead, please use the new events which all carry theframeKeyparameter, which can be used to handle frame specific events. The only exception to this isANIMATION_COMPLETE_KEY, which is a key specific version of the completion event. ANIMATION_UPDATE_EVENTis a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.ANIMATION_STOP_EVENTis a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of thestopmethods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)- The Game Object
Component.Animationcomponent has been renamed toAnimationStateand has moved namespace. It's now inPhaser.Animationsinstead ofGameObjects.Componentsto help differentiate it from theAnimationclass when browsing the documentation. - The
play,playReverse,playAfterDelay,playAfterRepeatandchainSprite and Animation Component methods can now all take aPhaser.Types.Animations.PlayAnimationConfigconfiguration object, as well as a string, as thekeyparameter. 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.createis 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.generateFrameNumbersis 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.generateFrameNamesis 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,playAfterDelayandplayAfterRepeatwill 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.skipMissedFramesis 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.addMixis 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.getMixis a new method that will return the mix duration between the two given animations.AnimationManager.removeMixis a new method that will remove the mixture between either two animations, or all mixtures for the given animation.AnimationState.removeis a new method that will remove a locally stored Animation instance from a Sprite.AnimationState.getis a new method that will return a locally stored Animation instance from the Sprite.AnimationState.existsis a new method that will check if a locally stored Animation exists on the Sprite.- The internal
AnimationState.removemethod has been renamed toglobalRemove. AnimationState.textureManageris a new property that references the global Texture Manager.AnimationState.animsis a new property that contains locally created Animations in a Custom Map.AnimationState.playandSprite.playno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.AnimationState.playReverseandSprite.playReverseno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.- The
AnimationState.delayedPlaymethod has been renamed toplayAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration. - The
AnimationState.stopOnRepeatmethod has been renamed tostopAfterRepeat - The
AnimationState.getCurrentKeymethod has been renamed togetName. AnimationState.getFrameNameis a new method that will return the key of the current Animation Frame, if an animation has been loaded.AnimationState.playAfterDelayandSprite.playAfterDelayare new methods that will play the given animation after the delay in ms expires.AnimationState.playAfterRepeatandSprite.playAfterRepeatare 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.chainmethod is now available on the Sprite class. - The
AnimationState.stopAfterDelaymethod is now available on the Sprite class. - The
AnimationState.stopAfterRepeatmethod is now available on the Sprite class. - The
AnimationState.stopOnFramemethod is now available on the Sprite class. AnimationManager.createFromAsepriteis 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.AnimationStatenow 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 optionalPlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.- The
PlayAnimationConfig.frameRateproperty lets you optionally override the animation frame rate. - The
PlayAnimationConfig.durationproperty lets you optionally override the animation duration. - The
PlayAnimationConfig.delayproperty lets you optionally override the animation delay. - The
PlayAnimationConfig.repeatproperty lets you optionally override the animation repeat counter. - The
PlayAnimationConfig.repeatDelayproperty lets you optionally override the animation repeat delay value. - The
PlayAnimationConfig.yoyoproperty lets you optionally override the animation yoyo boolean. - The
PlayAnimationConfig.showOnStartproperty lets you optionally override the animation show on start value. - The
PlayAnimationConfig.hideOnCompleteproperty lets you optionally override the animation hide on complete value. - The
PlayAnimationConfig.startFrameproperty lets you optionally set the animation frame to start on. - The
PlayAnimationConfig.timeScaleproperty lets you optionally set the animation time scale factor. AnimationState.delayCounteris a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animationSTARTevents fire. Fix #4426 (thanks @bdaenen)AnimationState.hasStartedis 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.showOnStartis a new boolean property that controls if the Game Object should havesetVisible(true)called on it when the animation starts.AnimationState.hideOnCompleteis a new boolean property that controls if the Game Object should havesetVisible(false)called on it when the animation completes.- The
AnimationState.chainmethod docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does! - The
AnimationState.setDelaymethod has been removed. It never actually worked and you can now perform the same thing by calling eitherplayAfterDelayor setting thedelayproperty in the play config. - The
AnimationState.getDelaymethod has been removed. You can now read thedelayproperty directly. - The
AnimationState.setRepeatmethod has been removed. You can achieve the same thing by setting therepeatproperty in the play config, or adjusting the publicrepeatCounterproperty if the animation has started. AnimationState.handleStartis a new internal private method that handles the animation start process.AnimationState.handleRepeatis a new internal private method that handles the animation repeat process.AnimationState.handleStopis a new internal private method that handles the animation stop process.AnimationState.handleCompleteis a new internal private method that handles the animation complete process.AnimationState.emitEventsis a new internal private method that emits animation events, cutting down on duplicate code.- The
AnimationState.restartmethod has a new optional boolean parameterresetRepeatswhich controls if you want to reset the repeat counter during the restart, or not. Animation.getTotalFramesis a new method that will return the total number of frames in the animation. You can access it viathis.anims.currentAnim.getTotalFramesfrom a Sprite.Animation.calculateDurationis a new method that calculates the duration, frameRate and msPerFrame for a given animation target.- The
BuildGameObjectAnimationfunction now uses thePlayAnimationConfigobject to set the values. Sprite.playReverseis a new method that allows you to play the given animation in reverse on the Sprite.Sprite.playAfterDelayis a new method that allows you to play the given animation on the Sprite after a delay.Sprite.stopis a new method that allows you to stop the current animation on the Sprite.AnimationManager.loadhas been removed as it's no longer required.AnimationManager.staggerPlayhas been fixed so you can now pass in negative stagger values.AnimationManager.staggerPlayhas a new optional boolean parameterstaggerFirst, which allows you to either include or exclude the first child in the stagger calculations.- The
Animation.completeAnimationmethod has been removed as it's no longer required. - The
Animation.loadmethod has been removed as it's no longer required. - The
Animation.setFramemethod has been removed as it's no longer required. - The
Animation.getFirstTickmethod has no longer needs theincludeDelayparameter, as it's handled byAnimationStatenow. - The
Animation.getFramesmethod has a new optional boolean parametersortFrameswhich will run a numeric sort on the frame names after constructing them, if a string-based frame is given. Types.Animations.Animationhas a new boolean propertysortFrames, which lets Phaser numerically sort the generated frames.AnimationState.timeScaleis a new public property that replaces the old private_timeScaleproperty.AnimationState.delayis a new public property that replaces the old private_delayproperty.AnimationState.repeatis a new public property that replaces the old private_repeatproperty.AnimationState.repeatDelayis a new public property that replaces the old private_repeatDelayproperty.AnimationState.yoyois a new public property that replaces the old private_yoyoproperty.AnimationState.inReverseis a new public property that replaces the old private_reverseproperty.AnimationState.startAnimationis a new public method that replaces the old private_startAnimationmethod.- The
AnimationState.getProgressmethod has been fixed so it will return correctly if the animation is playing in reverse. - The
AnimationState.globalRemovemethod will now always be called when an animation is removed from the global Animation Manager, not just once. - The
AnimationState.getRepeatmethod has now been removed. You can get the value from therepeatproperty. - The
AnimationState.setRepeatDelaymethod has now been removed. You can set the value using therepeatDelayconfig property, or changing it at run-time. AnimationState.completeis a new method that handles the completion in animation playback.- The
AnimationState.setTimeScalemethod has now been removed. You can set the value using thetimeScaleconfig property, or changing it at run-time. - The
AnimationState.getTimeScalemethod has now been removed. You can read the value using thetimeScaleproperty. - The
AnimationState.getTotalFramesmethod has been fixed and won't error if called when no animation is loaded. - The
AnimationState.setYoyomethod has now been removed. You can set the value using theyoyoconfig property, or changing it at run-time. - The
AnimationState.getYoyomethod has now been removed. You can read the value using theyoyoproperty. - The
AnimationState.stopAfterRepeatmethod now has an optional parameterrepeatCount, 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.updateFramemethod has now been removed. Everything is handled bysetCurrentFrameinstead, which removes one extra step out of the update process. GenerateFrameNameswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswould include the__BASEframe by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.GenerateFrameNumberscan now accept thestartandendparameters in reverse order, meaning you can now do{ start: 10, end: 1 }to create the animation in reverse.GenerateFrameNamescan now accept thestartandendparameters 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.createDynamicLayermethod has been renamed tocreateLayer. - The
Tilemap.createStaticLayermethod has been removed. UsecreateLayerinstead. - The
Tilemap.createBlankDynamicLayermethod has been renamed tocreateBlankLayer. - The
Tilemap.convertLayerToStaticmethod has been removed as it is no longer required. - The
TilemapLayerWebGLRendererfunction 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.TilemapOrientationTypeis a new type def that holds the 4 types of map orientation now supported.- The
Tile.updatePixelXYmethod now updates the tile XY position based on map type. ParseTilesetswill now correctly handle non-consecutive tile IDs. It also now correctly sets themaxIdproperty, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)Tilemap.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.LayerData.orientationis a new property that holds the tilemap layers orientation constant.LayerData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.MapData.orientationis a new property that holds the tilemap layers orientation constant.MapData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.Tilemaps.Components.HexagonalWorldToTileYis a new function that converts a world Y coordinate to hexagonal tile Y coordinate.Tilemaps.Components.StaggeredWorldToTileYis a new function that converts a world Y coordinate to staggered tile Y coordinate.Tilemaps.Components.HexagonalWorldToTileXYis a new function that converts world coordinates to hexagonal tile coordinates.Tilemaps.Components.IsometricWorldToTileXYis a new function that converts world coordinates to isometric tile coordinates.Tilemaps.Components.StaggeredWorldToTileXYis a new function that converts world coordinates to staggered tile coordinates.Tilemaps.Components.HexagonalTileToWorldYis a new function that converts a hexagonal Y coordinate to a world coordinate.Tilemaps.Components.StaggeredTileToWorldYis a new function that converts a staggered Y coordinate to a world coordinate.Tilemaps.Components.HexagonalTileToWorldXYis a new function that converts hexagonal tile coordinates to world coordinates.Tilemaps.Components.IsometricTileToWorldXYis a new function that converts isometric tile coordinates to world coordinates.Tilemaps.Components.StaggeredTileToWorldXYis a new function that converts staggered tile coordinates to world coordinates.Tilemaps.Components.GetTileToWorldXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldXXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetCullTilesFunctionis a new function that returns the correct culling function to use.Tilemaps.Components.HexagonalCullTilesis a new function that culls tiles in a hexagonal map.Tilemaps.Components.StaggeredCullTilesis a new function that culls tiles in a staggered map.Tilemaps.Components.IsometricCullTilesis a new function that culls tiles in a isometric map.Tilemaps.Components.CullBoundsis a new function that calculates the cull bounds for an orthogonal map.Tilemaps.Components.HexagonalCullBoundsis a new function that calculates the cull bounds for a hexagonal map.Tilemaps.Components.StaggeredCullBoundsis a new function that calculates the cull bounds for a staggered map.Tilemaps.Components.RunCullis a new function that runs the culling process from the combined bounds and tilemap.Tilemap._convertis a new internal private hash of tilemap conversion functions used by the public API.- The
Tilemap._isStaticCallmethod 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
GetTilesWithinWorldXYcomponent directly, saving lots of overhead. - The method
Tilemap.weightedRandomizehas changed so that the parameterweightedIndexesis now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional. - The method
TilemapLayer.weightedRandomizehas changed so that the parameterweightedIndexesis 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_SCENEis 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_SCENEis 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_SCENEis 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_SCENEis 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.addedToSceneis 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.removedFromSceneis 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 theremovedFromScenemethod now. - The
Containerwill 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.eventsis a new property that references the Scene's Event Emitter. This is now used internally.DisplayList.addChildCallbackis a new method that overrides the List callback and fires the new ADDED events.DisplayList.removeChildCallbackis a new method that overrides the List callback and fires the new REMOVED events.GameObjectCreator.eventsis a new property that references the Scene's Event Emitter. This is now used internally.GameObjectFactory.eventsis a new property that references the Scene's Event Emitter. This is now used internally.ProcessQueue.checkQueueis a new boolean property that will make sure only unique objects are added to the Process Queue.- The
Update Listnow uses the newcheckQueueproperty to ensure no duplicate objects are on the active list. DOMElementFactory,ExternFactory,ParticleManagerFactor,RopeFactoryandSpriteFactoryall no longer add the objects to the Update List, this is now handled by the ADDED events instead.Sprite,Rope,ParticleEmitterManager,ExternandDOMElementnow all override theaddedToSceneandremovedFromScenecallbacks to handle further set-up tasks.
Input Manager and Mouse Manager - New Features, API Changes and Bug Fixes
ScaleManager.refreshis now called when theGame.READYevent 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
inputMouseCapturehas been removed, as this is now split into 3 new config options: inputMousePreventDefaultDownis a new config option that allows you to controlpreventDefaultcalls specifically on mouse down events. Set it viainput.mouse.preventDefaultDownin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultUpis a new config option that allows you to controlpreventDefaultcalls specifically on mouse up events. Set it viainput.mouse.preventDefaultUpin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultMoveis a new config option that allows you to controlpreventDefaultcalls specifically on mouse move events. Set it viainput.mouse.preventDefaultMovein the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultWheelis a new config option that allows you to controlpreventDefaultcalls specifically on mouse wheel events. Set it viainput.mouse.preventDefaultWheelin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.- The
MouseManager.captureproperty has been removed, as this is now split into 3 new config options (see below) MouseManager.preventDefaultDownis a new boolean property, set via theinputMousePreventDefaultDownconfig option that allows you to toggle capture of mouse down events at runtime.MouseManager.preventDefaultUpis a new boolean property, set via theinputMousePreventDefaultUpconfig option that allows you to toggle capture of mouse up events at runtime.MouseManager.preventDefaultMoveis a new boolean property, set via theinputMousePreventDefaultMoveconfig option that allows you to toggle capture of mouse move events at runtime.MouseManager.preventDefaultWheelis a new boolean property, set via theinputMousePreventDefaultWheelconfig option that allows you to toggle capture of mouse wheel at runtime.- In the
MouseManagerthe 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
GamepadPluginwill now callrefreshPadsas 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 viathis.input.gamepad.pad1and 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._createdis 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.downwill 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
useHandCursorenabled, 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.shutdownmethod 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.processOverEventshas 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.tintTopLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTLwhich has now been removed.Tint.tintTopRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTRwhich has now been removed.Tint.tintBottomLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBLwhich has now been removed.Tint.tintBottomRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBRwhich has now been removed.- The property
Tint._isTintedhas been removed as it's no longer required. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they now read the color value asoutTint.bgrinstead ofoutTint.rgb. This allows the colors to remain in RGB order within the Tint component. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they no longer have a 3-way check on theoutTintEffectvalue. - The
Multi Pipeline,Bitmap Text,Render Texture,Text,TileSpriteandCameranow all read the tint values from the public properties instead of the private_tintTLetc ones. They also now set thetintEffectvalue directly from thetintFillproperty, removing another conditional check. - The function
GetColorFromValuehas been removed as it's no longer used internally. - The
Rope.tintFillproperty is now a boolean, not an integer, and can no longer take2as 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
getTintAppendFloatAlphaAndSwaphave been replaced withgetTintAppendFloatAlphainstead. - As a result of the change to the shader, the Multi Pipeline now uses the
WebGLRenderer.whiteTextureandtintEffectmode 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.whiteTextureis 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
TextureManagernow generates a new texture with the key__WHITEduring its boot process. This is a pure white 4x4 texture used by the Graphics pipelines. Config.images.whiteis 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
Bodyclass has a new boolean propertypushable(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.setPushableis a new chainable method that allows you to set thepushablestate of a Body.Arcade.Components.Pushableis 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.disableUpdateis a new method that will prevent the Arcade Physics Worldupdatemethod 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.enableUpdateis 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.customUpdateis a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. Iftruethe World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)Physics.Arcade.Body.setCollideWorldBoundsnow has a new optional parameteronWorldBoundswhich allows you to enable the Body'sonWorldBoundsproperty in the same call (thanks @samme)ArcadePhysics.Body.setMaxVelocityXis a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)ArcadePhysics.Body.setMaxVelocityYis a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)- The
PhysicsGroupconfig now has two new optional propertiesmaxVelocityXandmaxVelocityYwhich allows you to set the maximum velocity on bodies added to the Group (thanks @samme) - The
Arcade.Body.resetFlagsmethod has a new optional boolean parameterclear. If set, it clears thewasTouchingflags on the Body. This happens automatically whenBody.resetis called. Previous to this, the flags were not reset until the next physics step (thanks @samme) Physics.Arcade.ProcessXis a new set of functions, called by theSeparateXfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Physics.Arcade.ProcessYis a new set of functions, called by theSeparateYfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Arcade.Body.centervalues 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_STEPevent now has a new parameter: the delta argument (thanks @samme) - The Arcade Body
dragproperty 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 usedragyou will need to change any existing drag values to get the same effects as before. Convertdragtodrag ^ 60ordrag ^ fpsif you use a different step rate (thanks @samme)
New Features
Geom.Intersects.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Intersects.GetLineToPointsis 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.GetRaysFromPointToPolygonis 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.Translateis a new function that allows you to translate all the points of a polygon by the given values.Geom.Polygon.Simplifyis 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.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.getTweensOfhas a new parameterincludePending. 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.hasBootedis 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 theWebGLRenderer.addPipelinemethod, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)- The WebGL Renderer will now add the pipelines during the
bootmethod, instead ofinit. - You can now use
this.rendererfrom within a Scene, as it's now a Scene-level property and part of the Injection Map. Clock.addEventcan now take an existingTimerEventobject, as well as a config object. If aTimerEventis 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.removeEventis a new method that allows you to remove aTimerEvent, or an array of them, from all internal lists of the current Clock.Group.getMatchingis a new method that will return any members of the Group that match the given criteria, such asgetMatching('visible', true)(thanks @atursams)Utils.Array.SortByDigitsis 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 callingGroup.createMultipleorGroup.createFromConfig, can now accept the following new properties:setOrigin: { x, y, stepX, stepY }which are applied to the items created by the Group.Transform.copyPositionis a new method that will copy the position from the given object to the Game Object (thanks @samme)- The
Text.MeasureTextfunction, 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 newactualBoundingBoxAscentfunctions 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.GetCalcMatrixis 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,StarandTriangle. This dramatically reduces the amount of duplicate code across the API.Utils.Array.Matrix.Translateis a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.Vertor3.addScaleis 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
easeParamsin the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh) BitmapMask.createMaskis 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.clearMaskwill 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.Quaternionnow has a new propertyonChangeCallbackwhich, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.- The
Quaternion.setmethod has a new optional boolean parameterupdate(defaults totrue), which will call theonChangeCallbackif set. Quaternion.setFromEuleris a new method that will set the quaternion from the givenEulerobject, optionally calling theonChangeCallbackin the process.Quaternion.setFromRotationMatrixis a new method that will set the rotation of the quaternion from the given Matrix4.Vector3.setFromMatrixPositionis a new method that will set the components of the Vector3 based on the position of the given Matrix4.Vector3.setFromMatrixColumnis a new method that will set the components of the Vector3 based on the specified Matrix4 column.Vector3.fromArrayis a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.Vector3.minis a new method that will set the components of the Vector3 based on theMain.minbetween it and the given Vector3.Vector3.maxis a new method that will set the components of the Vector3 based on theMain.maxbetween it and the given Vector3.Vector3.addVectorsis a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.Vector3.addScalaris a new method that will multiply the components of the Vector3 by the scale value given.Vector3.applyMatrix3is a new method that will take a Matrix3 and apply it to the Vector3.Vector3.applyMatrix4is a new method that will take a Matrix4 and apply it to the Vector3.Vector3.projectViewMatrixis a new method that multiplies the Vector3 by the given view and projection matrices.Vector3.unprojectViewMatrixis a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.Matrix4.setValuesis a new method that allows you to set all of the matrix components individually. Most internal methods now use this.Matrix.multiplyToMat4is a new method that multiplies a Matrix4 by the givensrcMatrix4 and stores the results in theoutMatrix4.Matrix4.fromRotationXYTranslationis a new method that takes the rotation and position vectors and builds this Matrix4 from them.Matrix4.getMaxScaleOnAxisis a new method that will return the maximum axis scale from the Matrix4.Matrix4.lookAtRHis a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.Matrix4.transformis a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.Matrix4.multiplyMatricesis a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.Matrix4.premultiplyis a new method that takes a Matrix4 and multiplies it by the current Matrix4.Matrix4.getInverseis a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.CameraManager.getVisibleChildrenis a new method that is called internally by theCameraManager.rendermethod. It filters the DisplayList, so that Game Objects that pass thewillRendertest 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.setDampingis a new method that allows you to set theuseDampingproperty of a Body in a chainable way. Fix #5352 (thanks @juanitogan)- The
GameObjects.Graphics.fillGradientStylemethod 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.PipelineConfigis a new configuration object that you can set in the Game Config under thepipelineproperty. 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 thepipelineobject, or set it under therendersub-config.Utils.Object.DeepCopyis a new function that will recursively deep copy an array of object.Time.TimerEvent.getRemainingis a new method that returns the time interval until the next iteration of the Timer Event (thanks @samme)Time.TimerEvent.getRemainingSecondsis a new method that returns the time interval until the next iteration of the Timer Event in seconds (thanks @samme)Time.TimerEvent.getOverallRemainingis a new method that returns the time interval until the last iteration of the Timer Event (thanks @samme)Time.TimerEvent.getOverallRemainingSecondsis a new method that returns the time interval until the last iteration of the Timer Event in seconds (thanks @samme)GameObjects.Video.loadMediaStreamis 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.ColorSpectrumis 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.AsepriteFileis 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 viathis.load.asesprite(png, json).GameObject.displayListis 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
ShaderGame Object now supports being able to use a Render Texture as asampler2Dtexture on the shader #5423 (thanks @ccaleb) BaseSound.pan,HTMLAudioSound.panandWebAudioSound.panare 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.setPanis 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.PANis a new event dispatched by both Web Audio and HTML5 Audio Sound objects when their pan changes (thanks @pi-kei)
ColorMatrix
Phaser.Display.ColorMatrixis 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.setmethod allows you to set the values of a ColorMatrix. - The
ColorMatrix.resetmethod will reset the ColorMatrix to its default values. - The
ColorMatrix.getDatamethod will return the data in the ColorMatrix as a Float32Array, useful for setting in a shader uniform. - The
ColorMatrix.brightnessmethod lets you set the brightness of the ColorMatrix. - The
ColorMatrix.saturatemethod lets you set the saturation of the ColorMatrix. - The
ColorMatrix.desaturatemethod lets you desaturate the colors in the ColorMatrix. - The
ColorMatrix.huemethod lets you rotate the hues of the ColorMatrix by the given amount. - The
ColorMatrix.grayscalemethod converts the ColorMatrix to grayscale. - The
ColorMatrix.blackWhitemethod converts the ColorMatrix to black and whites. - The
ColorMatrix.contrastmethod lets you set the contrast of the ColorMatrix. - The
ColorMatrix.negativemethod converts the ColorMatrix to negative values. - The
ColorMatrix.desaturateLuminancemethod applies a desaturated luminance to the ColorMatrix. - The
ColorMatrix.sepiamethod applies a sepia tone to the ColorMatrix. - The
ColorMatrix.nightmethod applies a night time effect to the ColorMatrix. - The
ColorMatrix.lsdmethod applies a trippy color effect to the ColorMatrix. - The
ColorMatrix.brownmethod applies a brown tone to the ColorMatrix. - The
ColorMatrix.vintagePinholemethod applies a vintage pinhole color effect to the ColorMatrix. - The
ColorMatrix.kodachromemethod applies a kodachrome color effect to the ColorMatrix. - The
ColorMatrix.technicolormethod applies a technicolor color effect to the ColorMatrix. - The
ColorMatrix.polaroidmethod applies a polaroid color effect to the ColorMatrix. - The
ColorMatrix.shiftToBGRmethod shifts the values of the ColorMatrix into BGR order. - The
ColorMatrix.multiplymethod 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.Earcutand is fully documented. Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself. - The constant
Phaser.Renderer.WebGL.BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.FLOATvalue has been removed as it wasn't used internally. Pointer.downTimenow 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.upTimenow 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.getDurationmethod now uses the new PointerdownTimeandupTimevalues, 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
BaseShaderdefault vertex shader now includes theoutTexCoordvec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok) - When using the
GameObjectCreatorforContainersyou can now specify thechildrenproperty in the configuration object. Textures.Parsers.JSONHashwill now perform ahasOwnPropertycheck when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes fromJSON.parse. Fix #4768 (thanks @RollinSafary)- The
Camera3DPlugin 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.seekwill 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
inputWindowEventsis set in the Game Config, then theMouseManagerwill now listen for the events onwindow.topinstead of justwindow, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in atry/catchblock, as not all sites allow access towindow.top(specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow) MouseManager.isTopis a new boolean read-only property that flags if the mouse event listeners were attached towindow.top(true), or justwindow(false). By default Phaser will attemptwindow.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back towindowin those cases and set this property to false (thanks BunBunBun)Types.GameObjects.Text.GetTextSizeObjectis a new type def for the GetTextSize function results.Utils.Array.StableSorthas 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. Theinplacefunction has been removed, just callStableSort(array)directly now. All classes that usedStableSort.inplacehave 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.setOriginwill now callupdateDisplayOriginon the items array, otherwise the effects can't be seen when rendering.- You can now set the
ArcadeWorld.fixedStepproperty via theArcadeWorldConfigobject (thanks @samme) Utils.Array.NumerArraycan now accept thestartandendparameters in reverse order, i.e.10, 1will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.DataManager.Events.DESTROYis a new event that the Data Manager will listen for from its parent and then call its owndestroymethod when received.- The
Quaternionclass constructor will now default the values to0,0,0,1if they're not provided, making it an identity quaternion, rather than the0,0,0,0it was before. - You can now set the
ParticleEmitter.reservevalue via the emitter configuration object (thanks @vforsh) - Setting the
pixelArtconfig option will now setantialiasGLtofalse, as well asantialias. Fix #5309 (thanks @Vegita2) - The
Shapeclass now includes theComputedSizecomponent properties and methods directly in the class, rather than applying as a mixin.setSizeis now flagged as beingprivate, 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.maxParallelDownloadsvalue is now set to 6 if running on Android, or 32 on any other OS. This avoidsnet::ERR_FAILEDissues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary) - When running an Arcade Physics
overlaptest against aStaticBody, it will no longer set theblockedstates 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
LineGame 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
Quaternionclass now has 4 new private properties:_x,_y,_zand_wand 4 new getters and setters for the public versions. It also now passes most methods viasetto allow for the onChange callback to be invoked. This does not change the public-facing API. Groupnow extendsEventEmitter, allowing you to emit custom events from within a Group.Device.Audio.wavnow usesaudio/wavas thecanPlayTypecheck string, instead ofaudio/wav; codecs="1", which should allow iOS13 to play wav files again.- In the
Loader.FileTypes.TextFileconfig you can now override the type and cache destination for the file. Loader.MultiFilewill 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.tintvalue is now0xffffff(previously, it was0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh) SceneManager.startwill now reset theSceneSystems.sceneUpdatereference toNOOP. This gets set back to the Scene update method again duringbootScene(if it has one) and stops errors with external plugins and multi-part files that may triggerupdatebeforecreatehas been called. Fix #4629 (thanks @Osmose)Phaser.Scene.rendereris a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.- The
CanvasRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead. - Since iOS 13, iPads now identify as MacOS devices. A new maxTouchPoint check is now part of the
Device.OStests, stopping iPads from being flagged as desktop devices. Fix #5389 (thanks @SBCGames) - The
BitmapMask.prevFramebufferproperty has been removed as it's no longer required, due to the fbo stack in the renderer. - The
TextureManager.addGLTexturemethod has been updated so that thewidthandheightparameters are now optional. If not provided, and if available, they will be read from the given WebGLTexture instead (thanks @hexus) GameObjects.Components.Depth.depthListis 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
WebAudioSoundManagerwill no longer try to unlock itself if the Game hasn't already booted and been added to the DOM. It will now wait for theBOOTevent and unlock based on that. Fix #5439 (thanks @samme)
Bug Fixes
- The
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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
ProcessQueuewas emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar) - The
GridAlignaction didn't work if only theheightparameter was set. Fix #5019 (thanks @halilcakar) - The
Color.HSVToRGBfunction has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX) - Previously, the
easeParamsarray within a Tweenspropsobject, 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.setRenderToTextureitszoomandrotationvalues would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok) GameObjects.Shape.Gridwould render a white fill even if you passedundefinedas the fill color in the constructor. It now doesn't render cells if no fill color is given.- The
onMouseevents in the Input Manager didn't reset theactivePointerproperty 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
GetScreenOrientationfunction will now check forwindow.orientationfirst, 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 emitorientationchangeevents correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu) Time.Clock.addEventcan now take an instance of aTimerEventas its parameter. Fix #5294 (thanks @samme @EmilSV)GameConfig.audionow defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)- The
Loader.pathwas 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.getMatchingwould always return an empty array. It now returns matching children (thanks @samme)- The
ParticleManagerWebGLRenderernow 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
ParticleManagerCanvasRenderernow calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also usessetToContextinternally. 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
GraphicsWebGL Renderer will now default topathOpen = true. This fixes issues under WebGL where, for example, adding an arc and callingstrokePath, without first callingbeginPathwill no longer cause rendering artefacts when WebGL tries to close the path with a single tri. Graphics.strokeRoundedRectnow issuesmoveTocommands 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
snapshotin WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in theWebGLSnapshotfunction. Fix #4956 (thanks @gammafp @telinc1) Particles.EmitterOp.setMethodswill now reset bothonEmitandonUpdateto 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.EmitterOpnow cleanly separates between the different types of property configuration options.start | endwill now ease between the two values,min | maxwill pick a random value between them andrandom: []will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)- When setting both
transparent: trueandbackgroundColorin 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
EllipseGame Object now will update the width, height, and geometric position in thesetSizemethod (thanks @PhaserEditor2D) - When measuring the last word in a line in a
TextGame Object, it no longer adds extra white space to the end (thanks @rexrainbow) Utils.Array.Removewould 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.TriangleToLinewouldn't returntrueif 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)
BitmapMaskwould 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.
AtlasJSONFileno longer stores the JSON in the JSON Cache once the texture has been created.AtlasXMLFileno longer stores the XML in the XML Cache once the texture has been created.UnityAtlasFileno longer stores the Text in the Text Cache once the texture has been created.BitmapFontFileno longer stores the XML in the XML Cache once the texture has been created.- You can now use
TextureManager.removeto 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.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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#RESIZEevent no longer sends theresolutionas a parameter. - The
BaseCamera.resolutionproperty has been removed. - The internal private
BaseCamera._cx,_cy,_cwand_chproperties has been removed, usex,y,widthandheightinstead. - The
BaseCamera.preRendermethod no longer receives or uses theresolutionparameter. - The
Camera.preRendermethod no longer receives or uses theresolutionparameter. - The
CameraManager.onResizemethod no longer receives or uses theresolutionparameter. - The
Core.Config.resolutionproperty has been removed. - The
TextStyle.resolutionproperty 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
CanvasRendererno longer reads or uses the Game Config resolution property. - The
PipelineManager.resizemethod along withWebGLPipeline.resizeand anything else that extends them no longer receives or uses theresolutionparameter. - The
WebGLRenderer.resizeandonResizemethods no longer receives or uses theresolutionparameter. - The
ScaleManager.resolutionproperty 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.MoveTofunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.DOM.GetInnerHeightfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Bobclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsManagerclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsPluginclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Particles.EmitterOpclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.GetTextSizefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.MeasureTextfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.TextStylefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Input.CreatePixelPerfectHandlerfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapCircfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapRectfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Tilemapnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Componentsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.MatterGameObjectclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.PointerConstraintclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetPhysicsPluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetScenePluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Structs.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Tilemaps.Parsers.Tiledfunction has now been exposed on the Phaser namespace (thanks @samme) - Every single
Tilemap.Componentfunction 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.pipelinesis no longer a plain object containing pipeline instances. It's now an instance of thePipelineManagerclass. This instance is created during the init and boot phase of the renderer.- The
WebGLRenderer.currentPipelineproperty no longer exists, instead usePipelineManager.current. - The
WebGLRenderer.previousPipelineproperty no longer exists, instead usePipelineManager.previous. - The
WebGLRenderer.hasPipelinemethod no longer exists, instead usePipelineManager.has. - The
WebGLRenderer.getPipelinemethod no longer exists, instead usePipelineManager.get. - The
WebGLRenderer.removePipelinemethod no longer exists, instead usePipelineManager.remove. - The
WebGLRenderer.addPipelinemethod no longer exists, instead usePipelineManager.add. - The
WebGLRenderer.setPipelinemethod no longer exists, instead usePipelineManager.set. - The
WebGLRenderer.rebindPipelinemethod no longer exists, instead usePipelineManager.rebind. - The
WebGLRenderer.clearPipelinemethod no longer exists, instead usePipelineManager.clear.
The Pipeline Manager also offers the following new features:
- The
PipelineManager.resizemethod automatically handles resize events across all pipelines. - The
PipelineManager.preRendermethod calls the pre-render method of all pipelines. - The
PipelineManager.rendermethod calls the render method of all pipelines. - The
PipelineManager.postRendermethod calls the post-render method of all pipelines. - The
PipelineManager.setMultimethod automatically binds the Multi Texture Pipeline, Phasers default. - The
PipelineManager.clearmethod will clear the pipeline, store it inpreviousand free the renderer. - The
PipelineManager.rebindmethod will reset the rendering context and restore thepreviouspipeline, if set. - The
PipelineManager.copyFramemethod will copy asourceRender Target to thetargetRender Target, optionally setting the brightness of the copy. - The
PipelineManager.blitFramemethod will copy asourceRender Target to thetargetRender Target. UnlikecopyFrameno resizing takes place and you can optionally set the brightness and erase mode of the copy. - The
PipelineManager.copyFrameRectmethod binds thesourceRender Target and then copies a section of it to thetargetusinggl.copyTexSubImage2Drather than a shader, making it much faster if you don't need blending or preserving alpha details. - The
PipelineManager.copyToGamemethod pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws thesourceRender Target to it. Use when you need to render the final result to the game canvas. - The
PipelineManager.drawFramemethod will copy asourceRender Target, optionally to atargetRender Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy. - The
PipelineManager.blendFramesmethod draws thesource1andsource2Render Targets to thetargetRender Target using a linear blend effect, which is controlled by thestrengthparameter. - The
PipelineManager.blendFramesAdditivemethod draws thesource1andsource2Render Targets to thetargetRender Target using an additive blend effect, which is controlled by thestrengthparameter. - The
PipelineManager.clearFramemethod 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_PIPELINEfor the Bitmap Mask Pipeline.Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINEfor the Light 2D Pipeline.Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINEfor the Single Pipeline.Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINEfor the Multi Pipeline.Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINEfor the Rope Pipeline.Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINEfor the Point Light Pipeline.Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINEfor the Post FX Pipeline.Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINEfor 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.gameObjectproperty is a reference to the Game Object that owns the Post Pipeline, if any. - The
PostFXPipeline.colorMatrixproperty is a Color Matrix instance used by the draw shader. - The
PostFXPipeline.fullFrame1property is a reference to thefullFrame1Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.fullFrame2property is a reference to thefullFrame2Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.halfFrame1property is a reference to thehalfFrame1Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.halfFrame2property is a reference to thehalfFrame2Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.copyFramemethod will copy asourceRender Target to thetargetRender Target, optionally setting the brightness of the copy. - The
PostFXPipeline.blitFramemethod will copy asourceRender Target to thetargetRender Target. UnlikecopyFrameno resizing takes place and you can optionally set the brightness and erase mode of the copy. - The
PostFXPipeline.copyFrameRectmethod binds thesourceRender Target and then copies a section of it to thetargetusinggl.copyTexSubImage2Drather than a shader, making it much faster if you don't need blending or preserving alpha details. - The
PostFXPipeline.copyToGamemethod pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws thesourceRender Target to it. Use when you need to render the final result to the game canvas. - The
PostFXPipeline.drawFramemethod will copy asourceRender Target, optionally to atargetRender Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy. - The
PostFXPipeline.blendFramesmethod draws thesource1andsource2Render Targets to thetargetRender Target using a linear blend effect, which is controlled by thestrengthparameter. - The
PostFXPipeline.blendFramesAdditivemethod draws thesource1andsource2Render Targets to thetargetRender Target using an additive blend effect, which is controlled by thestrengthparameter. - The
PostFXPipeline.clearFramemethod clears the given Render Target. - The
PostFXPipeline.bindAndDrawmethod binds this pipeline and draws thesourceRender Target to thetargetRender 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:
TextureTintPipelineis now called theMultiPipeline.TextureTintStripPipelineis now called theRopePipeline.ForwardDiffuseLightPipelineis now called theLightPipeline.
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.fragis now calledLight.frag.TextureTint.fragis now calledMulti.frag.TextureTint.vertis now calledMulti.vert.
WebGL Pipelines Updates
Further pipeline changes are as follows:
- None of the shaders or pipelines use the
uViewMatrixanduModelMatrixuniforms 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.WebGLPipelineConfigis a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.Types.Renderer.WebGL.WebGLPipelineAttributesConfigis 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
rendererproperty automatically, so it's no longer required in the config. - All pipelines will now work out the
glproperty automatically, so it's no longer required in the config. - All pipelines will now extract the
nameproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexCapacityproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexSizeproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexDataproperty from the config, allowing you to set it externally. - All pipelines will now extract the
attributesproperty from the config, allowing you to set it externally. - All pipelines will now extract the
topologyproperty from the config, allowing you to set it externally. - The
WebGLPipeline.shouldFlushmethod now accepts an optional parameteramount. If given, it will returntrueif 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
RopePipelinenow extendsMultiPipelineand just changes the topology, vastly reducing the file size. - The
WebGLPipeline.flushLockedproperty 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.manageris a new property that is a reference to the WebGL Pipeline Manager.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLPipeline.forceZerois a new boolean property that sets if the pipeline should force the use of texture zero.WebGLPipeline.hasBootedis a new boolean property that is set once the pipeline has finished setting itself up and has booted.WebGLPipeline.isPostFXis a new boolean property that is only set by Post FX Pipelines to help identify them.WebGLPipeline.renderTargetsis a new property that holds an array of WebGL Render Targets belonging to the pipeline.WebGLPipeline.currentRenderTargetis a new property that holds a reference to the currently bound Render Target.WebGLPipeline.shadersis a new property that holds an array of all WebGLShader instances that belong to the pipeline.WebGLPipeline.currentShaderis a new property that holds a reference to the currently active shader within the pipeline.WebGLPipeline.configis a new property that holds the pipeline configuration object used to create it.WebGLPipeline.projectionMatrixis a new property that holds a Matrix4 used as the projection matrix for the pipeline.WebGLPipeline.setProjectionMatrixis a new method that allows you to set the ortho projection matrix of the pipeline.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLPipeline.setShaderis a new method that allows you to set the currently active shader within the pipeline.WebGLPipeline.getShaderByNameis a new method that allows you to get a shader from the pipeline based on its name.WebGLPipeline.setShadersFromConfigis 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.setGameObjectis a new method that custom pipelines can use in order to perform pre-batch tasks for the given Game Object.WebGLPipeline.setVertexBufferis 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.preBatchis 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.postBatchis 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.unbindis a new method that unbinds the current Render Target, if one is set.WebGLPipeline.batchVertis a new method that adds a single vertex to the vertex buffer and increments the count by 1.WebGLPipeline.batchQuadis 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.batchTriis 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.drawFillRectis a new method that pushes a filled rectangle into the vertex batch.WebGLPipeline.setTexture2Dis a new method that sets the texture to be bound to the next available texture unit.WebGLPipeline.bindTextureis a new method that immediately activates the given WebGL Texture and binds it to the requested slot.WebGLPipeline.bindRenderTargetis a new method that binds the given Render Target to a given texture slot.WebGLPipeline.setTimeis 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.onBootis a new hook you can override in your own pipelines that is called when the pipeline has booted.WebGLPipeline.onResizeis a new hook you can override in your own pipelines that is called when the pipeline is resized.WebGLPipeline.onDrawis a new hook you can override in your own pipelines that is called by Post FX Pipelines every timepostBatchis invoked.WebGLPipeline.onActiveis 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.onBindis 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.onRebindis 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.onBatchis 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.onPreBatchis 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.onPostBatchis 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.onPreRenderis a new hook you can override in your own pipelines that is called once, per frame, right before anything has been rendered.WebGLPipeline.onRenderis 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.onPostRenderis 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.onBeforeFlushis a new hook you can override in your own pipelines that is called immediately before thegl.bufferDataandgl.drawArrayscalls are made, so you can perform any final pre-render modifications.WebGLPipeline.onAfterFlushis a new hook you can override in your own pipelines that is called aftergl.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_FLUSHevent is dispatched by a WebGL Pipeline right after it has issued adrawArrayscommand. - The
WebGL.Pipelines.Events.BEFORE_FLUSHevent is dispatched by a WebGL Pipeline right before it is about to flush. - The
WebGL.Pipelines.Events.BINDevent is dispatched by a WebGL Pipeline when it is bound by the Pipeline Manager. - The
WebGL.Pipelines.Events.BOOTevent is dispatched by a WebGL Pipeline when it has finished booting. - The
WebGL.Pipelines.Events.DESTROYevent is dispatched by a WebGL Pipeline when it begins its destruction process. - The
WebGL.Pipelines.Events.REBINDevent is dispatched by a WebGL Pipeline when the Pipeline Manager resets and rebinds it. - The
WebGL.Pipelines.Events.RESIZEevent 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.set1fwill set a 1f uniform based on the given name.WebGLPipeline.set2fwill set a 2f uniform based on the given name.WebGLPipeline.set3fwill set a 3f uniform based on the given name.WebGLPipeline.set4fwill set a 4f uniform based on the given name.WebGLPipeline.set1fvwill set a 1fv uniform based on the given name.WebGLPipeline.set2fvwill set a 2fv uniform based on the given name.WebGLPipeline.set3fvwill set a 3fv uniform based on the given name.WebGLPipeline.set4fvwill set a 4fv uniform based on the given name.WebGLPipeline.set1ivwill set a 1iv uniform based on the given name.WebGLPipeline.set2ivwill set a 2iv uniform based on the given name.WebGLPipeline.set3ivwill set a 3iv uniform based on the given name.WebGLPipeline.set4ivwill set a 4iv uniform based on the given name.WebGLPipeline.set1iwill set a 1i uniform based on the given name.WebGLPipeline.set2iwill set a 2i uniform based on the given name.WebGLPipeline.set3iwill set a 3i uniform based on the given name.WebGLPipeline.set4iwill set a 4i uniform based on the given name.WebGLPipeline.setMatrix2fvwill set a matrix 2fv uniform based on the given name.WebGLPipeline.setMatrix3fvwill set a matrix 3fv uniform based on the given name.WebGLPipeline.setMatrix4fvwill 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.setFloat1has been removed. Please useset1finstead.WebGLPipeline.setFloat2has been removed. Please useset2finstead.WebGLPipeline.setFloat3has been removed. Please useset3finstead.WebGLPipeline.setFloat4has been removed. Please useset4finstead.WebGLPipeline.setFloat1vhas been removed. Please useset1fvinstead.WebGLPipeline.setFloat2vhas been removed. Please useset2fvinstead.WebGLPipeline.setFloat3vhas been removed. Please useset3fvinstead.WebGLPipeline.setFloat4vhas been removed. Please useset4fvinstead.WebGLPipeline.setInt1has been removed. Please useset1iinstead.WebGLPipeline.setInt2has been removed. Please useset2iinstead.WebGLPipeline.setInt3has been removed. Please useset3iinstead.WebGLPipeline.setInt4has been removed. Please useset4iinstead.WebGLPipeline.setMatrix1has been removed. Please usesetMatrix2fvinstead.WebGLPipeline.setMatrix2has been removed. Please usesetMatrix3fvinstead.WebGLPipeline.setMatrix3has been removed. Please usesetMatrix4fvinstead.
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.
hasPostPipelineis a new boolean property that indicates if the Game Object has one, or more post pipelines set.postPipelinesis a new property that contains an array of Post Pipelines owned by the Game Object.pipelineDatais a new object object to store pipeline specific data in.- The
setPipelinemethod has been updated with 2 new parameters:pipelineDataandcopyData. These allow you to populate the pipeline data object during setting. - You can now pass a pipeline instance to the
setPipelinemethod, as well as a string. setPostPipelineis 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.setPipelineDatais a new method that allows you to set a key/value pair into the pipeline data object in a chainable way.getPostPipelineis a new method that will return a Post Pipeline instance from the Game Object based on the given string, function or instance.- The
resetPipelinemethod has two new parametersresetPostPipelineandresetData, both false by default, that will reset the Post Pipelines and pipeline data accordingly. resetPostPipelineis a new method that will specifically reset just the Post Pipelines, and optionally the pipeline data.removePostPipelineis 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.colorMatrixproperty is an instance of a ColorMatrix class, used by the draw shader. - The
UtilityPipeline.copyShaderproperty is a reference to the Copy Shader. - The
UtilityPipeline.addShaderproperty is a reference to the additive blend shader. - The
UtilityPipeline.linearShaderproperty is a reference to the linear blend shader. - The
UtilityPipeline.colorMatrixShaderproperty is a reference to the color matrix (draw) shader. - The
UtilityPipeline.fullFrame1property is a full sized Render Target that can be used as a temporary buffer during post processing calls. - The
UtilityPipeline.fullFrame2property is a full sized Render Target that can be used as a temporary buffer during post processing calls. - The
UtilityPipeline.halfFrame1property 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.halfFrame2property 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.copyFramemethod will copy asourceRender Target to thetargetRender Target, optionally setting the brightness of the copy. - The
UtilityPipeline.blitFramemethod will copy asourceRender Target to thetargetRender Target. UnlikecopyFrameno resizing takes place and you can optionally set the brightness and erase mode of the copy. - The
UtilityPipeline.copyFrameRectmethod binds thesourceRender Target and then copies a section of it to thetargetusinggl.copyTexSubImage2Drather than a shader, making it much faster if you don't need blending or preserving alpha details. - The
UtilityPipeline.copyToGamemethod pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws thesourceRender Target to it. Use when you need to render the final result to the game canvas. - The
UtilityPipeline.drawFramemethod will copy asourceRender Target, optionally to atargetRender Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy. - The
UtilityPipeline.blendFramesmethod draws thesource1andsource2Render Targets to thetargetRender Target using a linear blend effect, which is controlled by thestrengthparameter. - The
UtilityPipeline.blendFramesAdditivemethod draws thesource1andsource2Render Targets to thetargetRender Target using an additive blend effect, which is controlled by thestrengthparameter. - The
UtilityPipeline.clearFramemethod clears the given Render Target. - The
UtilityPipeline.setUVsmethod allows you to set the UV values for the 6 vertices that make-up the quad belonging to the Utility Pipeline. - The
UtilityPipeline.setTargetUVsmethod 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.flipXmethod horizontally flips the UV coordinates of the quad used by the shaders. - The
UtilityPipeline.flipYmethod vertically flips the UV coordinates of the quad used by the shaders. - The
UtilityPipeline.resetUVsmethod 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis 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.batchPointLightmethod 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.batchLightVertmethod is a special internal method, used bybatchPointLightthat 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 (
inPositionandinColor), 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
calcMatrixproperty has been added, which Shape Game Objects use to maintain transform state during rendering. - The Graphics Pipeline no longer makes use of
tintEffector 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.setTexturehas 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.renderWebGLnow uses the standardGetCalcMatrixfunction, 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.pipelineproperty is a reference to the WebGL Pipeline that owns the WebGLShader instance. - The
WebGLShader.nameproperty is the name of the shader. - The
WebGLShader.rendererproperty is a reference to the WebGL Renderer. - The
WebGLShader.glproperty is a reference to the WebGL Rendering Context. - The
WebGLShader.programproperty is the WebGL Program created from the vertex and fragment shaders. - The
WebGLShader.attributesproperty is an array of objects that describe the vertex attributes of the shader. - The
WebGLShader.vertexComponentCountproperty is the total amount of vertex attribute components of 32-bit length. - The
WebGLShader.vertexSizeproperty is the size, in bytes, of a single vertex. - The
WebGLShader.uniformsproperty is an object that is automatically populated with all active uniforms in the shader. - The
WebGLShader.createAttributesmethod takes the vertex attributes config and parses it, creating the shader attributes. This is called automatically. - The
WebGLShader.bindmethod sets the program the shader uses as being active. Called automatically when the parent pipeline needs this shader. - The
WebGLShader.rebindmethod sets the program the shader uses as being active and resets all of the vertex attribute pointers. - The
WebGLShader.setAttribPointersmethod sets the vertex attribute pointers. Called automatically duringbind. - The
WebGLShader.createUniformsmethod populates theuniformsobject with details about all active uniforms. - The
WebGLShader.hasUniformmethod returns a boolean if the given uniform exists. - The
WebGLShader.resetUniformmethod resets the cached value for the given uniform. - The
WebGLShader.setUniform1method is an internal method used for setting a single value uniform on the shader. - The
WebGLShader.setUniform2method is an internal method used for setting a double value uniform on the shader. - The
WebGLShader.setUniform3method is an internal method used for setting a triple value uniform on the shader. - The
WebGLShader.setUniform4method is an internal method used for setting a quadruple value uniform on the shader. - The
WebGLShader.set1fmethod sets a 1f uniform based on the given name. - The
WebGLShader.set2fmethod sets a 2f uniform based on the given name. - The
WebGLShader.set3fmethod sets a 3f uniform based on the given name. - The
WebGLShader.set4fmethod sets a 4f uniform based on the given name. - The
WebGLShader.set1fvmethod sets a 1fv uniform based on the given name. - The
WebGLShader.set2fvmethod sets a 2fv uniform based on the given name. - The
WebGLShader.set3fvmethod sets a 3fv uniform based on the given name. - The
WebGLShader.set4fvmethod sets a 4fv uniform based on the given name. - The
WebGLShader.set1ivmethod sets a 1iv uniform based on the given name. - The
WebGLShader.set2ivmethod sets a 2iv uniform based on the given name. - The
WebGLShader.set3ivmethod sets a 3iv uniform based on the given name. - The
WebGLShader.set4ivmethod sets a 4iv uniform based on the given name. - The
WebGLShader.set1imethod sets a 1i uniform based on the given name. - The
WebGLShader.set2imethod sets a 2i uniform based on the given name. - The
WebGLShader.set3imethod sets a 3i uniform based on the given name. - The
WebGLShader.set4imethod sets a 4i uniform based on the given name. - The
WebGLShader.setMatrix2fvmethod sets a matrix 2fv uniform based on the given name. - The
WebGLShader.setMatrix3fvmethod sets a matrix 3fv uniform based on the given name. - The
WebGLShader.setMatrix4fvmethod sets a matrix 4fv uniform based on the given name. - The
WebGLShader.destroymethod 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.rendererproperty is a reference to the WebGL Renderer. - The
RenderTarget.framebufferproperty is the WebGLFramebuffer belonging to the Render Target. - The
RenderTarget.textureproperty is a WebGLTexture belonging to the Render Target and bound to the framebuffer. - The
RenderTarget.widthproperty is the width of the Render Target. - The
RenderTarget.heightproperty is the height of the Render Target. - The
RenderTarget.scaleproperty is the scale of the Render Target, applied to the dimensions during resize. - The
RenderTarget.minFilterproperty is the min filter of the texture. - The
RenderTarget.autoClearproperty is a boolean that controls if the Render Target is automatically cleared when bound. - The
RenderTarget.autoResizeproperty is a boolean that controls if the Render Target is automatically resized if the WebGLRenderer resizes. - The
RenderTarget.setAutoResizemethod lets you set the auto resize of the Render Target. - The
RenderTarget.resizemethod lets you resize the Render Target. - The
RenderTarget.bindmethod sets the Render Target as being the active fbo in the renderer and optionally clears and adjusts the viewport. - The
RenderTarget.adjustViewportmethod sets the viewport to match the Render Target dimensions. - The
RenderTarget.clearmethod disables the scissors, clears the Render Target and resets the scissors again. - The
RenderTarget.unbindmethod flushes the renderer and pops the Render Target framebuffer from the stack. - The
RenderTarget.destroymethod 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture that was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.WebGLRenderer.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLRenderer.unbindTexturesis a new method that will activate and then null bind all WebGL textures.Renderer.WebGL.Utils.parseFragmentShaderMaxTexturesis 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.getComponentCountfunction has been removed as this is no longer required internally.
WebGLRenderer New Features, Updates and API Changes
WebGLRenderer.instancedArraysExtensionis a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.WebGLRenderer.vaoExtensionis a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.WebGLRenderer.resetProgramis a new method that will rebind the current program, without flushing or changing any properties.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.WebGLRenderer.finalTypeis a new boolean property that signifies if the current Game Object being rendered is the final one in the list.- The
WebGLRenderer.updateCanvasTexturemethod will now setgl.UNPACK_PREMULTIPLY_ALPHA_WEBGLto 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.previousPipelineis a new property that is set during a call toclearPipelineand used during calls torebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.- The
WebGLRenderer.rebindPipelinemethod has been changed slightly. Previously, you had to specify thepipelineInstance, but this is now optional. If you don't, it will use the newpreviousPipelineproperty instead. If not set, or none given, it will now return without throwing gl errors as well. WebGLRenderer.defaultScissoris a new property that holds the default scissor dimensions for the renderer. This is modified duringresizeand avoids continuous array generation in thepreRenderloop.- The
WebGLRenderer.nativeTexturesarray has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in theTextureSourceobjects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy. - The
WebGLRenderer.deleteTexturemethod has a new optional boolean parameterresetwhich allows you to control if theWebGLRenderer.resetTexturesmethod is called, or not, after the texture is deleted. - The
WebGLRenderer.getMaxTexturesmethod has been removed. This is no longer needed as you can use theWebGLRenderer.maxTexturesproperty instead. - The
WebGLRenderer.setProgrammethod now returns a boolean.trueif the program was set, otherwisefalse. WebGLRenderer.setFloat1has been removed. UseWebGLPipeline.set1forWebGLShader.set1finstead.WebGLRenderer.setFloat2has been removed. UseWebGLPipeline.set2forWebGLShader.set2finstead.WebGLRenderer.setFloat3has been removed. UseWebGLPipeline.set3forWebGLShader.set3finstead.WebGLRenderer.setFloat4has been removed. UseWebGLPipeline.set4forWebGLShader.set4finstead.WebGLRenderer.setFloat1vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set1fvinstead.WebGLRenderer.setFloat2vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set2fvinstead.WebGLRenderer.setFloat3vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set3fvinstead.WebGLRenderer.setFloat4vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set4fvinstead.WebGLRenderer.setInt1has been removed. UseWebGLPipeline.set1fiorWebGLShader.set1iinstead.WebGLRenderer.setInt2has been removed. UseWebGLPipeline.set1fiorWebGLShader.set2iinstead.WebGLRenderer.setInt3has been removed. UseWebGLPipeline.set1fiorWebGLShader.set3iinstead.WebGLRenderer.setInt4has been removed. UseWebGLPipeline.set1fiorWebGLShader.set4iinstead.WebGLRenderer.setMatrix2has been removed. UseWebGLPipeline.setMatrix2fvorWebGLShader.setMatrix2fvinstead.WebGLRenderer.setMatrix3has been removed. UseWebGLPipeline.setMatrix3fvorWebGLShader.setMatrix3fvinstead.WebGLRenderer.setMatrix4has been removed. UseWebGLPipeline.setMatrix4fvorWebGLShader.setMatrix4fvinstead.- The
WebGLRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead. WebGLRenderer.fboStackis a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.WebGLRenderer.pushFramebufferis 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 ofsetFramebuffer. Remember to callpopFramebufferafter using it.WebGLRenderer.popFramebufferis a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.WebGLRenderer.setFramebufferhas a new optional boolean parameterresetTextureswhich will reset the WebGL Textures, if set totrue(which is the default).WebGLRenderer.isBootedis a new boolean property that lets you know if the renderer has fully finished booting.- The
WebGLRenderernow extends the Event Emitter, allowing you to listen to renderer specific events. WebGLRenderer.defaultCamerahas been removed as it's not used anywhere internally any longer.- The
WebGLRenderer.setVertexBuffermethod has been removed along with theWebGLRenderer.currentVertexBufferproperty. This is now set directly by the WebGL Pipeline, as needed. - The
WebGLRenderer.setIndexBuffermethod has been removed along with theWebGLRenderer.currentIndexBufferproperty. This is now set directly by the WebGL Pipeline, as needed. WebGLRenderer.resetScissoris a new method that will reset the gl scissor state to be the current scissor, if there is one, without modifying the stack.WebGLRenderer.resetViewportis a new method that will reset the gl viewport to the current renderer dimensions.WebGLRenderer.renderTargetis a new property that contains a Render Target that is bound to the renderer and kept resized to match it.WebGLRenderer.beginCaptureis a new method that will bind the renderers Render Target, so everything drawn is redirected to it.WebGLRenderer.endCaptureis a new method that will unbind the renderers Render Target and return it, preventing anything else from being drawn to it.WebGLRenderer.setProjectionMatrixis a new method that sets the global renderer projection matrix to the given dimensions.WebGLRenderer.resetProjectionMatrixis a new method that resets the renderer projection matrix back to match the renderer size.WebGLRenderer.getAspectRatiois 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:
projIdentityhas been removed.projPersphas been removed.modelRotateXhas been removed.modelRotateYhas been removed.modelRotateZhas been removed.viewLoadhas been removed.viewRotateXhas been removed.viewRotateYhas been removed.viewRotateZhas been removed.viewScalehas been removed.viewTranslatehas been removed.modelIdentityhas been removed.modelScalehas been removed.modelTranslatehas been removed.viewIdentityhas been removed.viewLoad2Dhas been removed.projOrthohas been removed.
WebGL and Canvas Renderer Events
Phaser.Renderer.Eventsis a new namespace for events emitted by the Canvas and WebGL Renderers.Renderer.Events.PRE_RENDERis a new event dispatched by the Phaser Renderer. This happens right at the start of the render process.Renderer.Events.RENDERis 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_RENDERis a new event dispatched by the Phaser Renderer. This happens right at the end of the render process.Renderer.Events.RESIZEis a new event dispatched by the Phaser Renderer whenever it is resized.
Canvas Renderer Updates
CanvasRenderer.isBootedis a new boolean property that lets you know if the renderer has fully finished booting.- The
CanvasRenderernow 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.renderToTextureproperty has been removed. Effects are now handled via pipelines. - The
Camera.renderToGameproperty has been removed. Effects are now handled via pipelines. - The
Camera.canvasproperty has been removed. Textures are handled by pipelines. - The
Camera.contextproperty has been removed. Textures are handled by pipelines. - The
Camera.glTextureproperty has been removed. GL Textures are handled by pipelines. - The
Camera.framebufferproperty has been removed. GL Framebuffers are handled by pipelines. - The
Camera.setRenderToTexturemethod has been removed. Effects are now handled via pipelines. - The
Camera.clearRenderToTexturemethod 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.zoomXis a new property that allows you to specifically set the horizontal zoom factor of a Camera.Camera.zoomYis a new property that allows you to specifically set the vertical zoom factor of a Camera.- The
Camera.setZoommethod now allows you to pass two parameters:xandy, to control thezoomXandzoomYvalues accordingly. - The
Camera.zoomproperty now returns an average of thezoomXandzoomYproperties. Cameras.Scene2D.Events.FOLLOW_UPDATEis 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
roundPixelsset it will now round the internal scroll factors andworldViewduring thepreRenderstep. 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.
SpineContaineris a new Game Object available viathis.add.spineContainerto 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.runtimeswhich will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo intoplugins/spine/in order for this to work and then runnpm 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-zeroerror 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.setAnimationmethod will now use thetrackIndexparameter ifignoreIfPlayingis set and run the check against this track index. Fix #4842 (thanks @vinerz) - The
SpineFilewill 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
destroymethod 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.gameDestroyis a new method that is called if the Game instance emits adestroyevent. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.SpineFilewill 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)SpineFilenow 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.willRenderis no longer hard-coded to returntrue. 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.renderTargetis a new property that contains aRenderTargetinstance, which is used for all drawing.- The
RenderTexture.framebufferproperty has been removed. You can now access this viaRenderTexture.renderTarget.framebuffer. - The
RenderTexture.glTextureproperty has been removed. You can now access this viaRenderTexture.renderTarget.texture. - The
RenderTexture.glproperty has been removed.
Render Textures have the following new features:
RenderTexture.beginDrawis a new method that allows you to create a batched draw to the Render Texture. Use this method to begin the batch.RenderTexture.batchDrawis 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 withbeginDraw. 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.batchDrawFrameis 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 withbeginDraw. 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.endDrawis 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
Groupto aRenderTexture. 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 fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.RenderTexture.fillwould 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.erasehas 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.colorproperty is an instance of the Color object that controls the color value of the light. - The
PointLight.intensityproperty sets the intensity of the light. The colors of the light are multiplied by this value during rendering. - The
PointLight.attenuationproperty sets the attenuation of the light, which is the force with which the light falls off from its center. - The
PointLight.radiusproperty 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.Meshis 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.Vertexis a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.Geom.Mesh.Faceis a new class that consists of references to the threeVertexinstances that construct a single Face in a Mesh and provides methods for manipulating them.Geom.Mesh.GenerateVertsis a new function that will return an array ofVertexandFaceobjects 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.GenerateGridVertsis a new function that will generate a series ofVertexobjects in a grid format, based on the givenGenerateGridConfigconfig 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.GenerateObjVertsis a new function that will generate a series ofVertexobjects 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.ParseObjis a new function that will parse a triangulated Wavefront OBJ file into model data into a format that theGenerateObjVertsfunction can consume.Geom.Mesh.ParseObjMaterialis 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.RotateFaceis a new function that will rotate a Face by a given amount, based on an optional center of rotation.Loader.OBJFileis 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
MeshFactorysignatures have changed toscene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first.indiciesis a new parameter that allows you to provide indexed vertex data to create the Mesh from, where theindiciesarray holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. Theindiciesarray is optional. If your data is not indexed, then simply passnullor an empty array for this parameter. - The
MeshGame 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.addVerticesis 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.addVerticesFromObjis a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the newOBJFilewith athis.load.objcall, 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.hideCCWis 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.modelPositionis a new Vector3 property that allows you to translate the position of all vertices in the Mesh.Mesh.modelRotationis a new Vector3 property that allows you to rotate all vertices in the Mesh.Mesh.modelScaleis a new Vector3 property that allows you to scale all vertices in the Mesh.Mesh.panXis a new function that will translate the view position of the Mesh on the x axis.Mesh.panYis a new function that will translate the view position of the Mesh on the y axis.Mesh.panZis a new function that will translate the view position of the Mesh on the z axis.Mesh.setPerspectiveis a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.Mesh.setOrthois a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.Mesh.clearis a new method that will destroy all Faces and Vertices and clear the Mesh.Mesh.depthSortis a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.Mesh.addVertexis a new method that allows you to add a new single Vertex into the Mesh.Mesh.addFaceis a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.Mesh.getFaceCountnew is a new method that will return the total number of Faces in the Mesh.Mesh.getVertexCountnew is a new method that will return the total number of Vertices in the Mesh.Mesh.getFacenew is a new method that will return a Face instance from the Mesh based on the given index.Mesh.getFaceAtnew 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.verticesis now an array ofGameObject.Vertexinstances, not a Float32Array.Mesh.facesis a new array ofGameObject.Faceinstances, which is populated during a call to methods likeaddVerticesoraddModel.Mesh.totalRenderedis a new property that holds the total number of Faces that were rendered in the previous frame.Mesh.setDebugis 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
BringToTopto 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
MeshGame Object now extends theSingleAlphacomponent 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 standardsetAlphamethods. 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
colorsparameter in the constructor, factory method andaddVerticesmethod. 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
alphasparameter in the constructor, factory method andaddVerticesmethod. If a number, instead of an array, it will be used as the alpha for all vertices created. Mesh.debugGraphicis a new property that holds the debug Graphics instance reference.Mesh.debugCallbackis a new property that holds the debug render callback.Mesh.renderDebugVertsis a new method that acts as the default render callback forsetDebugif none is provided.Mesh.preDestroyis a new method that will clean-up the Mesh arrays and debug references on destruction.Mesh.isDirtyis a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically inpreUpdateto avoid generating lots of math when nothing has changed.- The
Mesh.uvarray has been removed. All UV data is now bound in the Vertex instances. - The
Mesh.colorsarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.alphasarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.tintFillproperty is now abooleanand defaults tofalse.
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.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycoordinates. The character data includes the code, position, dimensions, and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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
setMaxWidthonDynamicBitmapText, 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
Animationclass no longer extendsEventEmitter, 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_KEYevents have been removed. Instead, please use the new events which all carry theframeKeyparameter, which can be used to handle frame specific events. The only exception to this isANIMATION_COMPLETE_KEY, which is a key specific version of the completion event. ANIMATION_UPDATE_EVENTis a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.ANIMATION_STOP_EVENTis a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of thestopmethods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)- The Game Object
Component.Animationcomponent has been renamed toAnimationStateand has moved namespace. It's now inPhaser.Animationsinstead ofGameObjects.Componentsto help differentiate it from theAnimationclass when browsing the documentation. - The
play,playReverse,playAfterDelay,playAfterRepeatandchainSprite and Animation Component methods can now all take aPhaser.Types.Animations.PlayAnimationConfigconfiguration object, as well as a string, as thekeyparameter. 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.createis 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.generateFrameNumbersis 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.generateFrameNamesis 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,playAfterDelayandplayAfterRepeatwill 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.skipMissedFramesis 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.addMixis 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.getMixis a new method that will return the mix duration between the two given animations.AnimationManager.removeMixis a new method that will remove the mixture between either two animations, or all mixtures for the given animation.AnimationState.removeis a new method that will remove a locally stored Animation instance from a Sprite.AnimationState.getis a new method that will return a locally stored Animation instance from the Sprite.AnimationState.existsis a new method that will check if a locally stored Animation exists on the Sprite.- The internal
AnimationState.removemethod has been renamed toglobalRemove. AnimationState.textureManageris a new property that references the global Texture Manager.AnimationState.animsis a new property that contains locally created Animations in a Custom Map.AnimationState.playandSprite.playno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.AnimationState.playReverseandSprite.playReverseno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.- The
AnimationState.delayedPlaymethod has been renamed toplayAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration. - The
AnimationState.stopOnRepeatmethod has been renamed tostopAfterRepeat - The
AnimationState.getCurrentKeymethod has been renamed togetName. AnimationState.getFrameNameis a new method that will return the key of the current Animation Frame, if an animation has been loaded.AnimationState.playAfterDelayandSprite.playAfterDelayare new methods that will play the given animation after the delay in ms expires.AnimationState.playAfterRepeatandSprite.playAfterRepeatare 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.chainmethod is now available on the Sprite class. - The
AnimationState.stopAfterDelaymethod is now available on the Sprite class. - The
AnimationState.stopAfterRepeatmethod is now available on the Sprite class. - The
AnimationState.stopOnFramemethod is now available on the Sprite class. AnimationManager.createFromAsepriteis 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.AnimationStatenow 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 optionalPlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.- The
PlayAnimationConfig.frameRateproperty lets you optionally override the animation frame rate. - The
PlayAnimationConfig.durationproperty lets you optionally override the animation duration. - The
PlayAnimationConfig.delayproperty lets you optionally override the animation delay. - The
PlayAnimationConfig.repeatproperty lets you optionally override the animation repeat counter. - The
PlayAnimationConfig.repeatDelayproperty lets you optionally override the animation repeat delay value. - The
PlayAnimationConfig.yoyoproperty lets you optionally override the animation yoyo boolean. - The
PlayAnimationConfig.showOnStartproperty lets you optionally override the animation show on start value. - The
PlayAnimationConfig.hideOnCompleteproperty lets you optionally override the animation hide on complete value. - The
PlayAnimationConfig.startFrameproperty lets you optionally set the animation frame to start on. - The
PlayAnimationConfig.timeScaleproperty lets you optionally set the animation time scale factor. AnimationState.delayCounteris a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animationSTARTevents fire. Fix #4426 (thanks @bdaenen)AnimationState.hasStartedis 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.showOnStartis a new boolean property that controls if the Game Object should havesetVisible(true)called on it when the animation starts.AnimationState.hideOnCompleteis a new boolean property that controls if the Game Object should havesetVisible(false)called on it when the animation completes.- The
AnimationState.chainmethod docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does! - The
AnimationState.setDelaymethod has been removed. It never actually worked and you can now perform the same thing by calling eitherplayAfterDelayor setting thedelayproperty in the play config. - The
AnimationState.getDelaymethod has been removed. You can now read thedelayproperty directly. - The
AnimationState.setRepeatmethod has been removed. You can achieve the same thing by setting therepeatproperty in the play config, or adjusting the publicrepeatCounterproperty if the animation has started. AnimationState.handleStartis a new internal private method that handles the animation start process.AnimationState.handleRepeatis a new internal private method that handles the animation repeat process.AnimationState.handleStopis a new internal private method that handles the animation stop process.AnimationState.handleCompleteis a new internal private method that handles the animation complete process.AnimationState.emitEventsis a new internal private method that emits animation events, cutting down on duplicate code.- The
AnimationState.restartmethod has a new optional boolean parameterresetRepeatswhich controls if you want to reset the repeat counter during the restart, or not. Animation.getTotalFramesis a new method that will return the total number of frames in the animation. You can access it viathis.anims.currentAnim.getTotalFramesfrom a Sprite.Animation.calculateDurationis a new method that calculates the duration, frameRate and msPerFrame for a given animation target.- The
BuildGameObjectAnimationfunction now uses thePlayAnimationConfigobject to set the values. Sprite.playReverseis a new method that allows you to play the given animation in reverse on the Sprite.Sprite.playAfterDelayis a new method that allows you to play the given animation on the Sprite after a delay.Sprite.stopis a new method that allows you to stop the current animation on the Sprite.AnimationManager.loadhas been removed as it's no longer required.AnimationManager.staggerPlayhas been fixed so you can now pass in negative stagger values.AnimationManager.staggerPlayhas a new optional boolean parameterstaggerFirst, which allows you to either include or exclude the first child in the stagger calculations.- The
Animation.completeAnimationmethod has been removed as it's no longer required. - The
Animation.loadmethod has been removed as it's no longer required. - The
Animation.setFramemethod has been removed as it's no longer required. - The
Animation.getFirstTickmethod has no longer needs theincludeDelayparameter, as it's handled byAnimationStatenow. - The
Animation.getFramesmethod has a new optional boolean parametersortFrameswhich will run a numeric sort on the frame names after constructing them, if a string-based frame is given. Types.Animations.Animationhas a new boolean propertysortFrames, which lets Phaser numerically sort the generated frames.AnimationState.timeScaleis a new public property that replaces the old private_timeScaleproperty.AnimationState.delayis a new public property that replaces the old private_delayproperty.AnimationState.repeatis a new public property that replaces the old private_repeatproperty.AnimationState.repeatDelayis a new public property that replaces the old private_repeatDelayproperty.AnimationState.yoyois a new public property that replaces the old private_yoyoproperty.AnimationState.inReverseis a new public property that replaces the old private_reverseproperty.AnimationState.startAnimationis a new public method that replaces the old private_startAnimationmethod.- The
AnimationState.getProgressmethod has been fixed so it will return correctly if the animation is playing in reverse. - The
AnimationState.globalRemovemethod will now always be called when an animation is removed from the global Animation Manager, not just once. - The
AnimationState.getRepeatmethod has now been removed. You can get the value from therepeatproperty. - The
AnimationState.setRepeatDelaymethod has now been removed. You can set the value using therepeatDelayconfig property, or changing it at run-time. AnimationState.completeis a new method that handles the completion in animation playback.- The
AnimationState.setTimeScalemethod has now been removed. You can set the value using thetimeScaleconfig property, or changing it at run-time. - The
AnimationState.getTimeScalemethod has now been removed. You can read the value using thetimeScaleproperty. - The
AnimationState.getTotalFramesmethod has been fixed and won't error if called when no animation is loaded. - The
AnimationState.setYoyomethod has now been removed. You can set the value using theyoyoconfig property, or changing it at run-time. - The
AnimationState.getYoyomethod has now been removed. You can read the value using theyoyoproperty. - The
AnimationState.stopAfterRepeatmethod now has an optional parameterrepeatCount, 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.updateFramemethod has now been removed. Everything is handled bysetCurrentFrameinstead, which removes one extra step out of the update process. GenerateFrameNameswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswould include the__BASEframe by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.GenerateFrameNumberscan now accept thestartandendparameters in reverse order, meaning you can now do{ start: 10, end: 1 }to create the animation in reverse.GenerateFrameNamescan now accept thestartandendparameters 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.createDynamicLayermethod has been renamed tocreateLayer. - The
Tilemap.createStaticLayermethod has been removed. UsecreateLayerinstead. - The
Tilemap.createBlankDynamicLayermethod has been renamed tocreateBlankLayer. - The
Tilemap.convertLayerToStaticmethod has been removed as it is no longer required. - The
TilemapLayerWebGLRendererfunction 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.TilemapOrientationTypeis a new type def that holds the 4 types of map orientation now supported.- The
Tile.updatePixelXYmethod now updates the tile XY position based on map type. ParseTilesetswill now correctly handle non-consecutive tile IDs. It also now correctly sets themaxIdproperty, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)Tilemap.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.LayerData.orientationis a new property that holds the tilemap layers orientation constant.LayerData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.MapData.orientationis a new property that holds the tilemap layers orientation constant.MapData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.Tilemaps.Components.HexagonalWorldToTileYis a new function that converts a world Y coordinate to hexagonal tile Y coordinate.Tilemaps.Components.StaggeredWorldToTileYis a new function that converts a world Y coordinate to staggered tile Y coordinate.Tilemaps.Components.HexagonalWorldToTileXYis a new function that converts world coordinates to hexagonal tile coordinates.Tilemaps.Components.IsometricWorldToTileXYis a new function that converts world coordinates to isometric tile coordinates.Tilemaps.Components.StaggeredWorldToTileXYis a new function that converts world coordinates to staggered tile coordinates.Tilemaps.Components.HexagonalTileToWorldYis a new function that converts a hexagonal Y coordinate to a world coordinate.Tilemaps.Components.StaggeredTileToWorldYis a new function that converts a staggered Y coordinate to a world coordinate.Tilemaps.Components.HexagonalTileToWorldXYis a new function that converts hexagonal tile coordinates to world coordinates.Tilemaps.Components.IsometricTileToWorldXYis a new function that converts isometric tile coordinates to world coordinates.Tilemaps.Components.StaggeredTileToWorldXYis a new function that converts staggered tile coordinates to world coordinates.Tilemaps.Components.GetTileToWorldXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldXXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetCullTilesFunctionis a new function that returns the correct culling function to use.Tilemaps.Components.HexagonalCullTilesis a new function that culls tiles in a hexagonal map.Tilemaps.Components.StaggeredCullTilesis a new function that culls tiles in a staggered map.Tilemaps.Components.IsometricCullTilesis a new function that culls tiles in a isometric map.Tilemaps.Components.CullBoundsis a new function that calculates the cull bounds for an orthogonal map.Tilemaps.Components.HexagonalCullBoundsis a new function that calculates the cull bounds for a hexagonal map.Tilemaps.Components.StaggeredCullBoundsis a new function that calculates the cull bounds for a staggered map.Tilemaps.Components.RunCullis a new function that runs the culling process from the combined bounds and tilemap.Tilemap._convertis a new internal private hash of tilemap conversion functions used by the public API.- The
Tilemap._isStaticCallmethod 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
GetTilesWithinWorldXYcomponent directly, saving lots of overhead. - The method
Tilemap.weightedRandomizehas changed so that the parameterweightedIndexesis now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional. - The method
TilemapLayer.weightedRandomizehas changed so that the parameterweightedIndexesis 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_SCENEis 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_SCENEis 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_SCENEis 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_SCENEis 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.addedToSceneis 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.removedFromSceneis 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 theremovedFromScenemethod now. - The
Containerwill 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.eventsis a new property that references the Scene's Event Emitter. This is now used internally.DisplayList.addChildCallbackis a new method that overrides the List callback and fires the new ADDED events.DisplayList.removeChildCallbackis a new method that overrides the List callback and fires the new REMOVED events.GameObjectCreator.eventsis a new property that references the Scene's Event Emitter. This is now used internally.GameObjectFactory.eventsis a new property that references the Scene's Event Emitter. This is now used internally.ProcessQueue.checkQueueis a new boolean property that will make sure only unique objects are added to the Process Queue.- The
Update Listnow uses the newcheckQueueproperty to ensure no duplicate objects are on the active list. DOMElementFactory,ExternFactory,ParticleManagerFactor,RopeFactoryandSpriteFactoryall no longer add the objects to the Update List, this is now handled by the ADDED events instead.Sprite,Rope,ParticleEmitterManager,ExternandDOMElementnow all override theaddedToSceneandremovedFromScenecallbacks to handle further set-up tasks.
Input Manager and Mouse Manager - New Features, API Changes and Bug Fixes
ScaleManager.refreshis now called when theGame.READYevent 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
inputMouseCapturehas been removed, as this is now split into 3 new config options: inputMousePreventDefaultDownis a new config option that allows you to controlpreventDefaultcalls specifically on mouse down events. Set it viainput.mouse.preventDefaultDownin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultUpis a new config option that allows you to controlpreventDefaultcalls specifically on mouse up events. Set it viainput.mouse.preventDefaultUpin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultMoveis a new config option that allows you to controlpreventDefaultcalls specifically on mouse move events. Set it viainput.mouse.preventDefaultMovein the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultWheelis a new config option that allows you to controlpreventDefaultcalls specifically on mouse wheel events. Set it viainput.mouse.preventDefaultWheelin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.- The
MouseManager.captureproperty has been removed, as this is now split into 3 new config options (see below) MouseManager.preventDefaultDownis a new boolean property, set via theinputMousePreventDefaultDownconfig option that allows you to toggle capture of mouse down events at runtime.MouseManager.preventDefaultUpis a new boolean property, set via theinputMousePreventDefaultUpconfig option that allows you to toggle capture of mouse up events at runtime.MouseManager.preventDefaultMoveis a new boolean property, set via theinputMousePreventDefaultMoveconfig option that allows you to toggle capture of mouse move events at runtime.MouseManager.preventDefaultWheelis a new boolean property, set via theinputMousePreventDefaultWheelconfig option that allows you to toggle capture of mouse wheel at runtime.- In the
MouseManagerthe 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
GamepadPluginwill now callrefreshPadsas 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 viathis.input.gamepad.pad1and 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._createdis 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.downwill 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
useHandCursorenabled, 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.shutdownmethod 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.processOverEventshas 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.tintTopLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTLwhich has now been removed.Tint.tintTopRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTRwhich has now been removed.Tint.tintBottomLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBLwhich has now been removed.Tint.tintBottomRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBRwhich has now been removed.- The property
Tint._isTintedhas been removed as it's no longer required. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they now read the color value asoutTint.bgrinstead ofoutTint.rgb. This allows the colors to remain in RGB order within the Tint component. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they no longer have a 3-way check on theoutTintEffectvalue. - The
Multi Pipeline,Bitmap Text,Render Texture,Text,TileSpriteandCameranow all read the tint values from the public properties instead of the private_tintTLetc ones. They also now set thetintEffectvalue directly from thetintFillproperty, removing another conditional check. - The function
GetColorFromValuehas been removed as it's no longer used internally. - The
Rope.tintFillproperty is now a boolean, not an integer, and can no longer take2as 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
getTintAppendFloatAlphaAndSwaphave been replaced withgetTintAppendFloatAlphainstead. - As a result of the change to the shader, the Multi Pipeline now uses the
WebGLRenderer.whiteTextureandtintEffectmode 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.whiteTextureis 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
TextureManagernow generates a new texture with the key__WHITEduring its boot process. This is a pure white 4x4 texture used by the Graphics pipelines. Config.images.whiteis 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
Bodyclass has a new boolean propertypushable(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.setPushableis a new chainable method that allows you to set thepushablestate of a Body.Arcade.Components.Pushableis 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.disableUpdateis a new method that will prevent the Arcade Physics Worldupdatemethod 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.enableUpdateis 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.customUpdateis a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. Iftruethe World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)Physics.Arcade.Body.setCollideWorldBoundsnow has a new optional parameteronWorldBoundswhich allows you to enable the Body'sonWorldBoundsproperty in the same call (thanks @samme)ArcadePhysics.Body.setMaxVelocityXis a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)ArcadePhysics.Body.setMaxVelocityYis a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)- The
PhysicsGroupconfig now has two new optional propertiesmaxVelocityXandmaxVelocityYwhich allows you to set the maximum velocity on bodies added to the Group (thanks @samme) - The
Arcade.Body.resetFlagsmethod has a new optional boolean parameterclear. If set, it clears thewasTouchingflags on the Body. This happens automatically whenBody.resetis called. Previous to this, the flags were not reset until the next physics step (thanks @samme) Physics.Arcade.ProcessXis a new set of functions, called by theSeparateXfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Physics.Arcade.ProcessYis a new set of functions, called by theSeparateYfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Arcade.Body.centervalues 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_STEPevent now has a new parameter: the delta argument (thanks @samme) - The Arcade Body
dragproperty 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 usedragyou will need to change any existing drag values to get the same effects as before. Convertdragtodrag ^ 60ordrag ^ fpsif you use a different step rate (thanks @samme)
New Features
Geom.Intersects.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Intersects.GetLineToPointsis 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.GetRaysFromPointToPolygonis 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.Translateis a new function that allows you to translate all the points of a polygon by the given values.Geom.Polygon.Simplifyis 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.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.getTweensOfhas a new parameterincludePending. 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.hasBootedis 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 theWebGLRenderer.addPipelinemethod, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)- The WebGL Renderer will now add the pipelines during the
bootmethod, instead ofinit. - You can now use
this.rendererfrom within a Scene, as it's now a Scene-level property and part of the Injection Map. Clock.addEventcan now take an existingTimerEventobject, as well as a config object. If aTimerEventis 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.removeEventis a new method that allows you to remove aTimerEvent, or an array of them, from all internal lists of the current Clock.Group.getMatchingis a new method that will return any members of the Group that match the given criteria, such asgetMatching('visible', true)(thanks @atursams)Utils.Array.SortByDigitsis 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 callingGroup.createMultipleorGroup.createFromConfig, can now accept the following new properties:setOrigin: { x, y, stepX, stepY }which are applied to the items created by the Group.Transform.copyPositionis a new method that will copy the position from the given object to the Game Object (thanks @samme)- The
Text.MeasureTextfunction, 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 newactualBoundingBoxAscentfunctions 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.GetCalcMatrixis 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,StarandTriangle. This dramatically reduces the amount of duplicate code across the API.Utils.Array.Matrix.Translateis a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.Vertor3.addScaleis 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
easeParamsin the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh) BitmapMask.createMaskis 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.clearMaskwill 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.Quaternionnow has a new propertyonChangeCallbackwhich, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.- The
Quaternion.setmethod has a new optional boolean parameterupdate(defaults totrue), which will call theonChangeCallbackif set. Quaternion.setFromEuleris a new method that will set the quaternion from the givenEulerobject, optionally calling theonChangeCallbackin the process.Quaternion.setFromRotationMatrixis a new method that will set the rotation of the quaternion from the given Matrix4.Vector3.setFromMatrixPositionis a new method that will set the components of the Vector3 based on the position of the given Matrix4.Vector3.setFromMatrixColumnis a new method that will set the components of the Vector3 based on the specified Matrix4 column.Vector3.fromArrayis a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.Vector3.minis a new method that will set the components of the Vector3 based on theMain.minbetween it and the given Vector3.Vector3.maxis a new method that will set the components of the Vector3 based on theMain.maxbetween it and the given Vector3.Vector3.addVectorsis a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.Vector3.addScalaris a new method that will multiply the components of the Vector3 by the scale value given.Vector3.applyMatrix3is a new method that will take a Matrix3 and apply it to the Vector3.Vector3.applyMatrix4is a new method that will take a Matrix4 and apply it to the Vector3.Vector3.projectViewMatrixis a new method that multiplies the Vector3 by the given view and projection matrices.Vector3.unprojectViewMatrixis a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.Matrix4.setValuesis a new method that allows you to set all of the matrix components individually. Most internal methods now use this.Matrix.multiplyToMat4is a new method that multiplies a Matrix4 by the givensrcMatrix4 and stores the results in theoutMatrix4.Matrix4.fromRotationXYTranslationis a new method that takes the rotation and position vectors and builds this Matrix4 from them.Matrix4.getMaxScaleOnAxisis a new method that will return the maximum axis scale from the Matrix4.Matrix4.lookAtRHis a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.Matrix4.transformis a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.Matrix4.multiplyMatricesis a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.Matrix4.premultiplyis a new method that takes a Matrix4 and multiplies it by the current Matrix4.Matrix4.getInverseis a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.CameraManager.getVisibleChildrenis a new method that is called internally by theCameraManager.rendermethod. It filters the DisplayList, so that Game Objects that pass thewillRendertest 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.setDampingis a new method that allows you to set theuseDampingproperty of a Body in a chainable way. Fix #5352 (thanks @juanitogan)- The
GameObjects.Graphics.fillGradientStylemethod 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.PipelineConfigis a new configuration object that you can set in the Game Config under thepipelineproperty. 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 thepipelineobject, or set it under therendersub-config.Utils.Object.DeepCopyis a new function that will recursively deep copy an array of object.Time.TimerEvent.getRemainingis a new method that returns the time interval until the next iteration of the Timer Event (thanks @samme)Time.TimerEvent.getRemainingSecondsis a new method that returns the time interval until the next iteration of the Timer Event in seconds (thanks @samme)Time.TimerEvent.getOverallRemainingis a new method that returns the time interval until the last iteration of the Timer Event (thanks @samme)Time.TimerEvent.getOverallRemainingSecondsis a new method that returns the time interval until the last iteration of the Timer Event in seconds (thanks @samme)GameObjects.Video.loadMediaStreamis 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.ColorSpectrumis 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.AsepriteFileis 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 viathis.load.asesprite(png, json).GameObject.displayListis 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
ShaderGame Object now supports being able to use a Render Texture as asampler2Dtexture on the shader #5423 (thanks @ccaleb) BaseSound.pan,HTMLAudioSound.panandWebAudioSound.panare 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.setPanis 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.PANis a new event dispatched by both Web Audio and HTML5 Audio Sound objects when their pan changes (thanks @pi-kei)
ColorMatrix
Phaser.Display.ColorMatrixis 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.setmethod allows you to set the values of a ColorMatrix. - The
ColorMatrix.resetmethod will reset the ColorMatrix to its default values. - The
ColorMatrix.getDatamethod will return the data in the ColorMatrix as a Float32Array, useful for setting in a shader uniform. - The
ColorMatrix.brightnessmethod lets you set the brightness of the ColorMatrix. - The
ColorMatrix.saturatemethod lets you set the saturation of the ColorMatrix. - The
ColorMatrix.desaturatemethod lets you desaturate the colors in the ColorMatrix. - The
ColorMatrix.huemethod lets you rotate the hues of the ColorMatrix by the given amount. - The
ColorMatrix.grayscalemethod converts the ColorMatrix to grayscale. - The
ColorMatrix.blackWhitemethod converts the ColorMatrix to black and whites. - The
ColorMatrix.contrastmethod lets you set the contrast of the ColorMatrix. - The
ColorMatrix.negativemethod converts the ColorMatrix to negative values. - The
ColorMatrix.desaturateLuminancemethod applies a desaturated luminance to the ColorMatrix. - The
ColorMatrix.sepiamethod applies a sepia tone to the ColorMatrix. - The
ColorMatrix.nightmethod applies a night time effect to the ColorMatrix. - The
ColorMatrix.lsdmethod applies a trippy color effect to the ColorMatrix. - The
ColorMatrix.brownmethod applies a brown tone to the ColorMatrix. - The
ColorMatrix.vintagePinholemethod applies a vintage pinhole color effect to the ColorMatrix. - The
ColorMatrix.kodachromemethod applies a kodachrome color effect to the ColorMatrix. - The
ColorMatrix.technicolormethod applies a technicolor color effect to the ColorMatrix. - The
ColorMatrix.polaroidmethod applies a polaroid color effect to the ColorMatrix. - The
ColorMatrix.shiftToBGRmethod shifts the values of the ColorMatrix into BGR order. - The
ColorMatrix.multiplymethod 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.Earcutand is fully documented. Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself. - The constant
Phaser.Renderer.WebGL.BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.FLOATvalue has been removed as it wasn't used internally. Pointer.downTimenow 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.upTimenow 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.getDurationmethod now uses the new PointerdownTimeandupTimevalues, 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
BaseShaderdefault vertex shader now includes theoutTexCoordvec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok) - When using the
GameObjectCreatorforContainersyou can now specify thechildrenproperty in the configuration object. Textures.Parsers.JSONHashwill now perform ahasOwnPropertycheck when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes fromJSON.parse. Fix #4768 (thanks @RollinSafary)- The
Camera3DPlugin 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.seekwill 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
inputWindowEventsis set in the Game Config, then theMouseManagerwill now listen for the events onwindow.topinstead of justwindow, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in atry/catchblock, as not all sites allow access towindow.top(specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow) MouseManager.isTopis a new boolean read-only property that flags if the mouse event listeners were attached towindow.top(true), or justwindow(false). By default Phaser will attemptwindow.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back towindowin those cases and set this property to false (thanks BunBunBun)Types.GameObjects.Text.GetTextSizeObjectis a new type def for the GetTextSize function results.Utils.Array.StableSorthas 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. Theinplacefunction has been removed, just callStableSort(array)directly now. All classes that usedStableSort.inplacehave 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.setOriginwill now callupdateDisplayOriginon the items array, otherwise the effects can't be seen when rendering.- You can now set the
ArcadeWorld.fixedStepproperty via theArcadeWorldConfigobject (thanks @samme) Utils.Array.NumerArraycan now accept thestartandendparameters in reverse order, i.e.10, 1will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.DataManager.Events.DESTROYis a new event that the Data Manager will listen for from its parent and then call its owndestroymethod when received.- The
Quaternionclass constructor will now default the values to0,0,0,1if they're not provided, making it an identity quaternion, rather than the0,0,0,0it was before. - You can now set the
ParticleEmitter.reservevalue via the emitter configuration object (thanks @vforsh) - Setting the
pixelArtconfig option will now setantialiasGLtofalse, as well asantialias. Fix #5309 (thanks @Vegita2) - The
Shapeclass now includes theComputedSizecomponent properties and methods directly in the class, rather than applying as a mixin.setSizeis now flagged as beingprivate, 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.maxParallelDownloadsvalue is now set to 6 if running on Android, or 32 on any other OS. This avoidsnet::ERR_FAILEDissues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary) - When running an Arcade Physics
overlaptest against aStaticBody, it will no longer set theblockedstates 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
LineGame 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
Quaternionclass now has 4 new private properties:_x,_y,_zand_wand 4 new getters and setters for the public versions. It also now passes most methods viasetto allow for the onChange callback to be invoked. This does not change the public-facing API. Groupnow extendsEventEmitter, allowing you to emit custom events from within a Group.Device.Audio.wavnow usesaudio/wavas thecanPlayTypecheck string, instead ofaudio/wav; codecs="1", which should allow iOS13 to play wav files again.- In the
Loader.FileTypes.TextFileconfig you can now override the type and cache destination for the file. Loader.MultiFilewill 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.tintvalue is now0xffffff(previously, it was0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh) SceneManager.startwill now reset theSceneSystems.sceneUpdatereference toNOOP. This gets set back to the Scene update method again duringbootScene(if it has one) and stops errors with external plugins and multi-part files that may triggerupdatebeforecreatehas been called. Fix #4629 (thanks @Osmose)Phaser.Scene.rendereris a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.- The
CanvasRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead. - Since iOS 13, iPads now identify as MacOS devices. A new maxTouchPoint check is now part of the
Device.OStests, stopping iPads from being flagged as desktop devices. Fix #5389 (thanks @SBCGames) - The
BitmapMask.prevFramebufferproperty has been removed as it's no longer required, due to the fbo stack in the renderer. - The
TextureManager.addGLTexturemethod has been updated so that thewidthandheightparameters are now optional. If not provided, and if available, they will be read from the given WebGLTexture instead (thanks @hexus) GameObjects.Components.Depth.depthListis 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
WebAudioSoundManagerwill no longer try to unlock itself if the Game hasn't already booted and been added to the DOM. It will now wait for theBOOTevent and unlock based on that. Fix #5439 (thanks @samme)
Bug Fixes
- The
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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
ProcessQueuewas emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar) - The
GridAlignaction didn't work if only theheightparameter was set. Fix #5019 (thanks @halilcakar) - The
Color.HSVToRGBfunction has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX) - Previously, the
easeParamsarray within a Tweenspropsobject, 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.setRenderToTextureitszoomandrotationvalues would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok) GameObjects.Shape.Gridwould render a white fill even if you passedundefinedas the fill color in the constructor. It now doesn't render cells if no fill color is given.- The
onMouseevents in the Input Manager didn't reset theactivePointerproperty 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
GetScreenOrientationfunction will now check forwindow.orientationfirst, 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 emitorientationchangeevents correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu) Time.Clock.addEventcan now take an instance of aTimerEventas its parameter. Fix #5294 (thanks @samme @EmilSV)GameConfig.audionow defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)- The
Loader.pathwas 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.getMatchingwould always return an empty array. It now returns matching children (thanks @samme)- The
ParticleManagerWebGLRenderernow 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
ParticleManagerCanvasRenderernow calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also usessetToContextinternally. 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
GraphicsWebGL Renderer will now default topathOpen = true. This fixes issues under WebGL where, for example, adding an arc and callingstrokePath, without first callingbeginPathwill no longer cause rendering artefacts when WebGL tries to close the path with a single tri. Graphics.strokeRoundedRectnow issuesmoveTocommands 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
snapshotin WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in theWebGLSnapshotfunction. Fix #4956 (thanks @gammafp @telinc1) Particles.EmitterOp.setMethodswill now reset bothonEmitandonUpdateto 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.EmitterOpnow cleanly separates between the different types of property configuration options.start | endwill now ease between the two values,min | maxwill pick a random value between them andrandom: []will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)- When setting both
transparent: trueandbackgroundColorin 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
EllipseGame Object now will update the width, height, and geometric position in thesetSizemethod (thanks @PhaserEditor2D) - When measuring the last word in a line in a
TextGame Object, it no longer adds extra white space to the end (thanks @rexrainbow) Utils.Array.Removewould 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.TriangleToLinewouldn't returntrueif 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)
BitmapMaskwould 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.
AtlasJSONFileno longer stores the JSON in the JSON Cache once the texture has been created.AtlasXMLFileno longer stores the XML in the XML Cache once the texture has been created.UnityAtlasFileno longer stores the Text in the Text Cache once the texture has been created.BitmapFontFileno longer stores the XML in the XML Cache once the texture has been created.- You can now use
TextureManager.removeto 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.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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#RESIZEevent no longer sends theresolutionas a parameter. - The
BaseCamera.resolutionproperty has been removed. - The internal private
BaseCamera._cx,_cy,_cwand_chproperties has been removed, usex,y,widthandheightinstead. - The
BaseCamera.preRendermethod no longer receives or uses theresolutionparameter. - The
Camera.preRendermethod no longer receives or uses theresolutionparameter. - The
CameraManager.onResizemethod no longer receives or uses theresolutionparameter. - The
Core.Config.resolutionproperty has been removed. - The
TextStyle.resolutionproperty 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
CanvasRendererno longer reads or uses the Game Config resolution property. - The
PipelineManager.resizemethod along withWebGLPipeline.resizeand anything else that extends them no longer receives or uses theresolutionparameter. - The
WebGLRenderer.resizeandonResizemethods no longer receives or uses theresolutionparameter. - The
ScaleManager.resolutionproperty 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.MoveTofunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.DOM.GetInnerHeightfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Bobclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsManagerclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsPluginclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Particles.EmitterOpclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.GetTextSizefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.MeasureTextfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.TextStylefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Input.CreatePixelPerfectHandlerfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapCircfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapRectfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Tilemapnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Componentsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.MatterGameObjectclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.PointerConstraintclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetPhysicsPluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetScenePluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Structs.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Tilemaps.Parsers.Tiledfunction has now been exposed on the Phaser namespace (thanks @samme) - Every single
Tilemap.Componentfunction 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.pipelinesis no longer a plain object containing pipeline instances. It's now an instance of thePipelineManagerclass. This instance is created during the init and boot phase of the renderer.- The
WebGLRenderer.currentPipelineproperty no longer exists, instead usePipelineManager.current. - The
WebGLRenderer.previousPipelineproperty no longer exists, instead usePipelineManager.previous. - The
WebGLRenderer.hasPipelinemethod no longer exists, instead usePipelineManager.has. - The
WebGLRenderer.getPipelinemethod no longer exists, instead usePipelineManager.get. - The
WebGLRenderer.removePipelinemethod no longer exists, instead usePipelineManager.remove. - The
WebGLRenderer.addPipelinemethod no longer exists, instead usePipelineManager.add. - The
WebGLRenderer.setPipelinemethod no longer exists, instead usePipelineManager.set. - The
WebGLRenderer.rebindPipelinemethod no longer exists, instead usePipelineManager.rebind. - The
WebGLRenderer.clearPipelinemethod no longer exists, instead usePipelineManager.clear.
The Pipeline Manager also offers the following new features:
- The
PipelineManager.resizemethod automatically handles resize events across all pipelines. - The
PipelineManager.preRendermethod calls the pre-render method of all pipelines. - The
PipelineManager.rendermethod calls the render method of all pipelines. - The
PipelineManager.postRendermethod calls the post-render method of all pipelines. - The
PipelineManager.setMultimethod automatically binds the Multi Texture Pipeline, Phasers default. - The
PipelineManager.clearmethod will clear the pipeline, store it inpreviousand free the renderer. - The
PipelineManager.rebindmethod will reset the rendering context and restore thepreviouspipeline, if set. - The
PipelineManager.copyFramemethod will copy asourceRender Target to thetargetRender Target, optionally setting the brightness of the copy. - The
PipelineManager.blitFramemethod will copy asourceRender Target to thetargetRender Target. UnlikecopyFrameno resizing takes place and you can optionally set the brightness and erase mode of the copy. - The
PipelineManager.copyFrameRectmethod binds thesourceRender Target and then copies a section of it to thetargetusinggl.copyTexSubImage2Drather than a shader, making it much faster if you don't need blending or preserving alpha details. - The
PipelineManager.copyToGamemethod pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws thesourceRender Target to it. Use when you need to render the final result to the game canvas. - The
PipelineManager.drawFramemethod will copy asourceRender Target, optionally to atargetRender Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy. - The
PipelineManager.blendFramesmethod draws thesource1andsource2Render Targets to thetargetRender Target using a linear blend effect, which is controlled by thestrengthparameter. - The
PipelineManager.blendFramesAdditivemethod draws thesource1andsource2Render Targets to thetargetRender Target using an additive blend effect, which is controlled by thestrengthparameter. - The
PipelineManager.clearFramemethod 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_PIPELINEfor the Bitmap Mask Pipeline.Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINEfor the Light 2D Pipeline.Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINEfor the Single Pipeline.Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINEfor the Multi Pipeline.Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINEfor the Rope Pipeline.Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINEfor the Point Light Pipeline.Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINEfor the Post FX Pipeline.Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINEfor 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.gameObjectproperty is a reference to the Game Object that owns the Post Pipeline, if any. - The
PostFXPipeline.colorMatrixproperty is a Color Matrix instance used by the draw shader. - The
PostFXPipeline.fullFrame1property is a reference to thefullFrame1Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.fullFrame2property is a reference to thefullFrame2Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.halfFrame1property is a reference to thehalfFrame1Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.halfFrame2property is a reference to thehalfFrame2Render Target that belongs to the Utility Pipeline, as it's commonly used in post processing. - The
PostFXPipeline.copyFramemethod will copy asourceRender Target to thetargetRender Target, optionally setting the brightness of the copy. - The
PostFXPipeline.blitFramemethod will copy asourceRender Target to thetargetRender Target. UnlikecopyFrameno resizing takes place and you can optionally set the brightness and erase mode of the copy. - The
PostFXPipeline.copyFrameRectmethod binds thesourceRender Target and then copies a section of it to thetargetusinggl.copyTexSubImage2Drather than a shader, making it much faster if you don't need blending or preserving alpha details. - The
PostFXPipeline.copyToGamemethod pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws thesourceRender Target to it. Use when you need to render the final result to the game canvas. - The
PostFXPipeline.drawFramemethod will copy asourceRender Target, optionally to atargetRender Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy. - The
PostFXPipeline.blendFramesmethod draws thesource1andsource2Render Targets to thetargetRender Target using a linear blend effect, which is controlled by thestrengthparameter. - The
PostFXPipeline.blendFramesAdditivemethod draws thesource1andsource2Render Targets to thetargetRender Target using an additive blend effect, which is controlled by thestrengthparameter. - The
PostFXPipeline.clearFramemethod clears the given Render Target. - The
PostFXPipeline.bindAndDrawmethod binds this pipeline and draws thesourceRender Target to thetargetRender 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:
TextureTintPipelineis now called theMultiPipeline.TextureTintStripPipelineis now called theRopePipeline.ForwardDiffuseLightPipelineis now called theLightPipeline.
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.fragis now calledLight.frag.TextureTint.fragis now calledMulti.frag.TextureTint.vertis now calledMulti.vert.
WebGL Pipelines Updates
Further pipeline changes are as follows:
- None of the shaders or pipelines use the
uViewMatrixanduModelMatrixuniforms 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.WebGLPipelineConfigis a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.Types.Renderer.WebGL.WebGLPipelineAttributesConfigis 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
rendererproperty automatically, so it's no longer required in the config. - All pipelines will now work out the
glproperty automatically, so it's no longer required in the config. - All pipelines will now extract the
nameproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexCapacityproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexSizeproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexDataproperty from the config, allowing you to set it externally. - All pipelines will now extract the
attributesproperty from the config, allowing you to set it externally. - All pipelines will now extract the
topologyproperty from the config, allowing you to set it externally. - The
WebGLPipeline.shouldFlushmethod now accepts an optional parameteramount. If given, it will returntrueif 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
RopePipelinenow extendsMultiPipelineand just changes the topology, vastly reducing the file size. - The
WebGLPipeline.flushLockedproperty 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.manageris a new property that is a reference to the WebGL Pipeline Manager.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLPipeline.forceZerois a new boolean property that sets if the pipeline should force the use of texture zero.WebGLPipeline.hasBootedis a new boolean property that is set once the pipeline has finished setting itself up and has booted.WebGLPipeline.isPostFXis a new boolean property that is only set by Post FX Pipelines to help identify them.WebGLPipeline.renderTargetsis a new property that holds an array of WebGL Render Targets belonging to the pipeline.WebGLPipeline.currentRenderTargetis a new property that holds a reference to the currently bound Render Target.WebGLPipeline.shadersis a new property that holds an array of all WebGLShader instances that belong to the pipeline.WebGLPipeline.currentShaderis a new property that holds a reference to the currently active shader within the pipeline.WebGLPipeline.configis a new property that holds the pipeline configuration object used to create it.WebGLPipeline.projectionMatrixis a new property that holds a Matrix4 used as the projection matrix for the pipeline.WebGLPipeline.setProjectionMatrixis a new method that allows you to set the ortho projection matrix of the pipeline.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLPipeline.setShaderis a new method that allows you to set the currently active shader within the pipeline.WebGLPipeline.getShaderByNameis a new method that allows you to get a shader from the pipeline based on its name.WebGLPipeline.setShadersFromConfigis 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.setGameObjectis a new method that custom pipelines can use in order to perform pre-batch tasks for the given Game Object.WebGLPipeline.setVertexBufferis 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.preBatchis 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.postBatchis 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.unbindis a new method that unbinds the current Render Target, if one is set.WebGLPipeline.batchVertis a new method that adds a single vertex to the vertex buffer and increments the count by 1.WebGLPipeline.batchQuadis 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.batchTriis 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.drawFillRectis a new method that pushes a filled rectangle into the vertex batch.WebGLPipeline.setTexture2Dis a new method that sets the texture to be bound to the next available texture unit.WebGLPipeline.bindTextureis a new method that immediately activates the given WebGL Texture and binds it to the requested slot.WebGLPipeline.bindRenderTargetis a new method that binds the given Render Target to a given texture slot.WebGLPipeline.setTimeis 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.onBootis a new hook you can override in your own pipelines that is called when the pipeline has booted.WebGLPipeline.onResizeis a new hook you can override in your own pipelines that is called when the pipeline is resized.WebGLPipeline.onDrawis a new hook you can override in your own pipelines that is called by Post FX Pipelines every timepostBatchis invoked.WebGLPipeline.onActiveis 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.onBindis 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.onRebindis 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.onBatchis 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.onPreBatchis 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.onPostBatchis 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.onPreRenderis a new hook you can override in your own pipelines that is called once, per frame, right before anything has been rendered.WebGLPipeline.onRenderis 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.onPostRenderis 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.onBeforeFlushis a new hook you can override in your own pipelines that is called immediately before thegl.bufferDataandgl.drawArrayscalls are made, so you can perform any final pre-render modifications.WebGLPipeline.onAfterFlushis a new hook you can override in your own pipelines that is called aftergl.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_FLUSHevent is dispatched by a WebGL Pipeline right after it has issued adrawArrayscommand. - The
WebGL.Pipelines.Events.BEFORE_FLUSHevent is dispatched by a WebGL Pipeline right before it is about to flush. - The
WebGL.Pipelines.Events.BINDevent is dispatched by a WebGL Pipeline when it is bound by the Pipeline Manager. - The
WebGL.Pipelines.Events.BOOTevent is dispatched by a WebGL Pipeline when it has finished booting. - The
WebGL.Pipelines.Events.DESTROYevent is dispatched by a WebGL Pipeline when it begins its destruction process. - The
WebGL.Pipelines.Events.REBINDevent is dispatched by a WebGL Pipeline when the Pipeline Manager resets and rebinds it. - The
WebGL.Pipelines.Events.RESIZEevent 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.set1fwill set a 1f uniform based on the given name.WebGLPipeline.set2fwill set a 2f uniform based on the given name.WebGLPipeline.set3fwill set a 3f uniform based on the given name.WebGLPipeline.set4fwill set a 4f uniform based on the given name.WebGLPipeline.set1fvwill set a 1fv uniform based on the given name.WebGLPipeline.set2fvwill set a 2fv uniform based on the given name.WebGLPipeline.set3fvwill set a 3fv uniform based on the given name.WebGLPipeline.set4fvwill set a 4fv uniform based on the given name.WebGLPipeline.set1ivwill set a 1iv uniform based on the given name.WebGLPipeline.set2ivwill set a 2iv uniform based on the given name.WebGLPipeline.set3ivwill set a 3iv uniform based on the given name.WebGLPipeline.set4ivwill set a 4iv uniform based on the given name.WebGLPipeline.set1iwill set a 1i uniform based on the given name.WebGLPipeline.set2iwill set a 2i uniform based on the given name.WebGLPipeline.set3iwill set a 3i uniform based on the given name.WebGLPipeline.set4iwill set a 4i uniform based on the given name.WebGLPipeline.setMatrix2fvwill set a matrix 2fv uniform based on the given name.WebGLPipeline.setMatrix3fvwill set a matrix 3fv uniform based on the given name.WebGLPipeline.setMatrix4fvwill 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.setFloat1has been removed. Please useset1finstead.WebGLPipeline.setFloat2has been removed. Please useset2finstead.WebGLPipeline.setFloat3has been removed. Please useset3finstead.WebGLPipeline.setFloat4has been removed. Please useset4finstead.WebGLPipeline.setFloat1vhas been removed. Please useset1fvinstead.WebGLPipeline.setFloat2vhas been removed. Please useset2fvinstead.WebGLPipeline.setFloat3vhas been removed. Please useset3fvinstead.WebGLPipeline.setFloat4vhas been removed. Please useset4fvinstead.WebGLPipeline.setInt1has been removed. Please useset1iinstead.WebGLPipeline.setInt2has been removed. Please useset2iinstead.WebGLPipeline.setInt3has been removed. Please useset3iinstead.WebGLPipeline.setInt4has been removed. Please useset4iinstead.WebGLPipeline.setMatrix1has been removed. Please usesetMatrix2fvinstead.WebGLPipeline.setMatrix2has been removed. Please usesetMatrix3fvinstead.WebGLPipeline.setMatrix3has been removed. Please usesetMatrix4fvinstead.
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.
hasPostPipelineis a new boolean property that indicates if the Game Object has one, or more post pipelines set.postPipelinesis a new property that contains an array of Post Pipelines owned by the Game Object.pipelineDatais a new object object to store pipeline specific data in.- The
setPipelinemethod has been updated with 2 new parameters:pipelineDataandcopyData. These allow you to populate the pipeline data object during setting. - You can now pass a pipeline instance to the
setPipelinemethod, as well as a string. setPostPipelineis 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.setPipelineDatais a new method that allows you to set a key/value pair into the pipeline data object in a chainable way.getPostPipelineis a new method that will return a Post Pipeline instance from the Game Object based on the given string, function or instance.- The
resetPipelinemethod has two new parametersresetPostPipelineandresetData, both false by default, that will reset the Post Pipelines and pipeline data accordingly. resetPostPipelineis a new method that will specifically reset just the Post Pipelines, and optionally the pipeline data.removePostPipelineis 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.colorMatrixproperty is an instance of a ColorMatrix class, used by the draw shader. - The
UtilityPipeline.copyShaderproperty is a reference to the Copy Shader. - The
UtilityPipeline.addShaderproperty is a reference to the additive blend shader. - The
UtilityPipeline.linearShaderproperty is a reference to the linear blend shader. - The
UtilityPipeline.colorMatrixShaderproperty is a reference to the color matrix (draw) shader. - The
UtilityPipeline.fullFrame1property is a full sized Render Target that can be used as a temporary buffer during post processing calls. - The
UtilityPipeline.fullFrame2property is a full sized Render Target that can be used as a temporary buffer during post processing calls. - The
UtilityPipeline.halfFrame1property 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.halfFrame2property 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.copyFramemethod will copy asourceRender Target to thetargetRender Target, optionally setting the brightness of the copy. - The
UtilityPipeline.blitFramemethod will copy asourceRender Target to thetargetRender Target. UnlikecopyFrameno resizing takes place and you can optionally set the brightness and erase mode of the copy. - The
UtilityPipeline.copyFrameRectmethod binds thesourceRender Target and then copies a section of it to thetargetusinggl.copyTexSubImage2Drather than a shader, making it much faster if you don't need blending or preserving alpha details. - The
UtilityPipeline.copyToGamemethod pops the framebuffer from the renderers FBO stack and sets that as the active target, then draws thesourceRender Target to it. Use when you need to render the final result to the game canvas. - The
UtilityPipeline.drawFramemethod will copy asourceRender Target, optionally to atargetRender Target, using the given ColorMatrix, allowing for full control over the luminance values used during the copy. - The
UtilityPipeline.blendFramesmethod draws thesource1andsource2Render Targets to thetargetRender Target using a linear blend effect, which is controlled by thestrengthparameter. - The
UtilityPipeline.blendFramesAdditivemethod draws thesource1andsource2Render Targets to thetargetRender Target using an additive blend effect, which is controlled by thestrengthparameter. - The
UtilityPipeline.clearFramemethod clears the given Render Target. - The
UtilityPipeline.setUVsmethod allows you to set the UV values for the 6 vertices that make-up the quad belonging to the Utility Pipeline. - The
UtilityPipeline.setTargetUVsmethod 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.flipXmethod horizontally flips the UV coordinates of the quad used by the shaders. - The
UtilityPipeline.flipYmethod vertically flips the UV coordinates of the quad used by the shaders. - The
UtilityPipeline.resetUVsmethod 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis 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.batchPointLightmethod 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.batchLightVertmethod is a special internal method, used bybatchPointLightthat 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 (
inPositionandinColor), 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
calcMatrixproperty has been added, which Shape Game Objects use to maintain transform state during rendering. - The Graphics Pipeline no longer makes use of
tintEffector 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.setTexturehas 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.renderWebGLnow uses the standardGetCalcMatrixfunction, 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.pipelineproperty is a reference to the WebGL Pipeline that owns the WebGLShader instance. - The
WebGLShader.nameproperty is the name of the shader. - The
WebGLShader.rendererproperty is a reference to the WebGL Renderer. - The
WebGLShader.glproperty is a reference to the WebGL Rendering Context. - The
WebGLShader.programproperty is the WebGL Program created from the vertex and fragment shaders. - The
WebGLShader.attributesproperty is an array of objects that describe the vertex attributes of the shader. - The
WebGLShader.vertexComponentCountproperty is the total amount of vertex attribute components of 32-bit length. - The
WebGLShader.vertexSizeproperty is the size, in bytes, of a single vertex. - The
WebGLShader.uniformsproperty is an object that is automatically populated with all active uniforms in the shader. - The
WebGLShader.createAttributesmethod takes the vertex attributes config and parses it, creating the shader attributes. This is called automatically. - The
WebGLShader.bindmethod sets the program the shader uses as being active. Called automatically when the parent pipeline needs this shader. - The
WebGLShader.rebindmethod sets the program the shader uses as being active and resets all of the vertex attribute pointers. - The
WebGLShader.setAttribPointersmethod sets the vertex attribute pointers. Called automatically duringbind. - The
WebGLShader.createUniformsmethod populates theuniformsobject with details about all active uniforms. - The
WebGLShader.hasUniformmethod returns a boolean if the given uniform exists. - The
WebGLShader.resetUniformmethod resets the cached value for the given uniform. - The
WebGLShader.setUniform1method is an internal method used for setting a single value uniform on the shader. - The
WebGLShader.setUniform2method is an internal method used for setting a double value uniform on the shader. - The
WebGLShader.setUniform3method is an internal method used for setting a triple value uniform on the shader. - The
WebGLShader.setUniform4method is an internal method used for setting a quadruple value uniform on the shader. - The
WebGLShader.set1fmethod sets a 1f uniform based on the given name. - The
WebGLShader.set2fmethod sets a 2f uniform based on the given name. - The
WebGLShader.set3fmethod sets a 3f uniform based on the given name. - The
WebGLShader.set4fmethod sets a 4f uniform based on the given name. - The
WebGLShader.set1fvmethod sets a 1fv uniform based on the given name. - The
WebGLShader.set2fvmethod sets a 2fv uniform based on the given name. - The
WebGLShader.set3fvmethod sets a 3fv uniform based on the given name. - The
WebGLShader.set4fvmethod sets a 4fv uniform based on the given name. - The
WebGLShader.set1ivmethod sets a 1iv uniform based on the given name. - The
WebGLShader.set2ivmethod sets a 2iv uniform based on the given name. - The
WebGLShader.set3ivmethod sets a 3iv uniform based on the given name. - The
WebGLShader.set4ivmethod sets a 4iv uniform based on the given name. - The
WebGLShader.set1imethod sets a 1i uniform based on the given name. - The
WebGLShader.set2imethod sets a 2i uniform based on the given name. - The
WebGLShader.set3imethod sets a 3i uniform based on the given name. - The
WebGLShader.set4imethod sets a 4i uniform based on the given name. - The
WebGLShader.setMatrix2fvmethod sets a matrix 2fv uniform based on the given name. - The
WebGLShader.setMatrix3fvmethod sets a matrix 3fv uniform based on the given name. - The
WebGLShader.setMatrix4fvmethod sets a matrix 4fv uniform based on the given name. - The
WebGLShader.destroymethod 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.rendererproperty is a reference to the WebGL Renderer. - The
RenderTarget.framebufferproperty is the WebGLFramebuffer belonging to the Render Target. - The
RenderTarget.textureproperty is a WebGLTexture belonging to the Render Target and bound to the framebuffer. - The
RenderTarget.widthproperty is the width of the Render Target. - The
RenderTarget.heightproperty is the height of the Render Target. - The
RenderTarget.scaleproperty is the scale of the Render Target, applied to the dimensions during resize. - The
RenderTarget.minFilterproperty is the min filter of the texture. - The
RenderTarget.autoClearproperty is a boolean that controls if the Render Target is automatically cleared when bound. - The
RenderTarget.autoResizeproperty is a boolean that controls if the Render Target is automatically resized if the WebGLRenderer resizes. - The
RenderTarget.setAutoResizemethod lets you set the auto resize of the Render Target. - The
RenderTarget.resizemethod lets you resize the Render Target. - The
RenderTarget.bindmethod sets the Render Target as being the active fbo in the renderer and optionally clears and adjusts the viewport. - The
RenderTarget.adjustViewportmethod sets the viewport to match the Render Target dimensions. - The
RenderTarget.clearmethod disables the scissors, clears the Render Target and resets the scissors again. - The
RenderTarget.unbindmethod flushes the renderer and pops the Render Target framebuffer from the stack. - The
RenderTarget.destroymethod 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture that was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.WebGLRenderer.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLRenderer.unbindTexturesis a new method that will activate and then null bind all WebGL textures.Renderer.WebGL.Utils.parseFragmentShaderMaxTexturesis 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.getComponentCountfunction has been removed as this is no longer required internally.
WebGLRenderer New Features, Updates and API Changes
WebGLRenderer.instancedArraysExtensionis a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.WebGLRenderer.vaoExtensionis a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.WebGLRenderer.resetProgramis a new method that will rebind the current program, without flushing or changing any properties.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.WebGLRenderer.finalTypeis a new boolean property that signifies if the current Game Object being rendered is the final one in the list.- The
WebGLRenderer.updateCanvasTexturemethod will now setgl.UNPACK_PREMULTIPLY_ALPHA_WEBGLto 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.previousPipelineis a new property that is set during a call toclearPipelineand used during calls torebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.- The
WebGLRenderer.rebindPipelinemethod has been changed slightly. Previously, you had to specify thepipelineInstance, but this is now optional. If you don't, it will use the newpreviousPipelineproperty instead. If not set, or none given, it will now return without throwing gl errors as well. WebGLRenderer.defaultScissoris a new property that holds the default scissor dimensions for the renderer. This is modified duringresizeand avoids continuous array generation in thepreRenderloop.- The
WebGLRenderer.nativeTexturesarray has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in theTextureSourceobjects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy. - The
WebGLRenderer.deleteTexturemethod has a new optional boolean parameterresetwhich allows you to control if theWebGLRenderer.resetTexturesmethod is called, or not, after the texture is deleted. - The
WebGLRenderer.getMaxTexturesmethod has been removed. This is no longer needed as you can use theWebGLRenderer.maxTexturesproperty instead. - The
WebGLRenderer.setProgrammethod now returns a boolean.trueif the program was set, otherwisefalse. WebGLRenderer.setFloat1has been removed. UseWebGLPipeline.set1forWebGLShader.set1finstead.WebGLRenderer.setFloat2has been removed. UseWebGLPipeline.set2forWebGLShader.set2finstead.WebGLRenderer.setFloat3has been removed. UseWebGLPipeline.set3forWebGLShader.set3finstead.WebGLRenderer.setFloat4has been removed. UseWebGLPipeline.set4forWebGLShader.set4finstead.WebGLRenderer.setFloat1vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set1fvinstead.WebGLRenderer.setFloat2vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set2fvinstead.WebGLRenderer.setFloat3vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set3fvinstead.WebGLRenderer.setFloat4vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set4fvinstead.WebGLRenderer.setInt1has been removed. UseWebGLPipeline.set1fiorWebGLShader.set1iinstead.WebGLRenderer.setInt2has been removed. UseWebGLPipeline.set1fiorWebGLShader.set2iinstead.WebGLRenderer.setInt3has been removed. UseWebGLPipeline.set1fiorWebGLShader.set3iinstead.WebGLRenderer.setInt4has been removed. UseWebGLPipeline.set1fiorWebGLShader.set4iinstead.WebGLRenderer.setMatrix2has been removed. UseWebGLPipeline.setMatrix2fvorWebGLShader.setMatrix2fvinstead.WebGLRenderer.setMatrix3has been removed. UseWebGLPipeline.setMatrix3fvorWebGLShader.setMatrix3fvinstead.WebGLRenderer.setMatrix4has been removed. UseWebGLPipeline.setMatrix4fvorWebGLShader.setMatrix4fvinstead.- The
WebGLRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead. WebGLRenderer.fboStackis a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.WebGLRenderer.pushFramebufferis 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 ofsetFramebuffer. Remember to callpopFramebufferafter using it.WebGLRenderer.popFramebufferis a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.WebGLRenderer.setFramebufferhas a new optional boolean parameterresetTextureswhich will reset the WebGL Textures, if set totrue(which is the default).WebGLRenderer.isBootedis a new boolean property that lets you know if the renderer has fully finished booting.- The
WebGLRenderernow extends the Event Emitter, allowing you to listen to renderer specific events. WebGLRenderer.defaultCamerahas been removed as it's not used anywhere internally any longer.- The
WebGLRenderer.setVertexBuffermethod has been removed along with theWebGLRenderer.currentVertexBufferproperty. This is now set directly by the WebGL Pipeline, as needed. - The
WebGLRenderer.setIndexBuffermethod has been removed along with theWebGLRenderer.currentIndexBufferproperty. This is now set directly by the WebGL Pipeline, as needed. WebGLRenderer.resetScissoris a new method that will reset the gl scissor state to be the current scissor, if there is one, without modifying the stack.WebGLRenderer.resetViewportis a new method that will reset the gl viewport to the current renderer dimensions.WebGLRenderer.renderTargetis a new property that contains a Render Target that is bound to the renderer and kept resized to match it.WebGLRenderer.beginCaptureis a new method that will bind the renderers Render Target, so everything drawn is redirected to it.WebGLRenderer.endCaptureis a new method that will unbind the renderers Render Target and return it, preventing anything else from being drawn to it.WebGLRenderer.setProjectionMatrixis a new method that sets the global renderer projection matrix to the given dimensions.WebGLRenderer.resetProjectionMatrixis a new method that resets the renderer projection matrix back to match the renderer size.WebGLRenderer.getAspectRatiois 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:
projIdentityhas been removed.projPersphas been removed.modelRotateXhas been removed.modelRotateYhas been removed.modelRotateZhas been removed.viewLoadhas been removed.viewRotateXhas been removed.viewRotateYhas been removed.viewRotateZhas been removed.viewScalehas been removed.viewTranslatehas been removed.modelIdentityhas been removed.modelScalehas been removed.modelTranslatehas been removed.viewIdentityhas been removed.viewLoad2Dhas been removed.projOrthohas been removed.
WebGL and Canvas Renderer Events
Phaser.Renderer.Eventsis a new namespace for events emitted by the Canvas and WebGL Renderers.Renderer.Events.PRE_RENDERis a new event dispatched by the Phaser Renderer. This happens right at the start of the render process.Renderer.Events.RENDERis 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_RENDERis a new event dispatched by the Phaser Renderer. This happens right at the end of the render process.Renderer.Events.RESIZEis a new event dispatched by the Phaser Renderer whenever it is resized.
Canvas Renderer Updates
CanvasRenderer.isBootedis a new boolean property that lets you know if the renderer has fully finished booting.- The
CanvasRenderernow 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.renderToTextureproperty has been removed. Effects are now handled via pipelines. - The
Camera.renderToGameproperty has been removed. Effects are now handled via pipelines. - The
Camera.canvasproperty has been removed. Textures are handled by pipelines. - The
Camera.contextproperty has been removed. Textures are handled by pipelines. - The
Camera.glTextureproperty has been removed. GL Textures are handled by pipelines. - The
Camera.framebufferproperty has been removed. GL Framebuffers are handled by pipelines. - The
Camera.setRenderToTexturemethod has been removed. Effects are now handled via pipelines. - The
Camera.clearRenderToTexturemethod 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.zoomXis a new property that allows you to specifically set the horizontal zoom factor of a Camera.Camera.zoomYis a new property that allows you to specifically set the vertical zoom factor of a Camera.- The
Camera.setZoommethod now allows you to pass two parameters:xandy, to control thezoomXandzoomYvalues accordingly. - The
Camera.zoomproperty now returns an average of thezoomXandzoomYproperties. Cameras.Scene2D.Events.FOLLOW_UPDATEis 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
roundPixelsset it will now round the internal scroll factors andworldViewduring thepreRenderstep. 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.
SpineContaineris a new Game Object available viathis.add.spineContainerto 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.runtimeswhich will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo intoplugins/spine/in order for this to work and then runnpm 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-zeroerror 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.setAnimationmethod will now use thetrackIndexparameter ifignoreIfPlayingis set and run the check against this track index. Fix #4842 (thanks @vinerz) - The
SpineFilewill 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
destroymethod 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.gameDestroyis a new method that is called if the Game instance emits adestroyevent. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.SpineFilewill 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)SpineFilenow 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.willRenderis no longer hard-coded to returntrue. 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.renderTargetis a new property that contains aRenderTargetinstance, which is used for all drawing.- The
RenderTexture.framebufferproperty has been removed. You can now access this viaRenderTexture.renderTarget.framebuffer. - The
RenderTexture.glTextureproperty has been removed. You can now access this viaRenderTexture.renderTarget.texture. - The
RenderTexture.glproperty has been removed.
Render Textures have the following new features:
RenderTexture.beginDrawis a new method that allows you to create a batched draw to the Render Texture. Use this method to begin the batch.RenderTexture.batchDrawis 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 withbeginDraw. 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.batchDrawFrameis 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 withbeginDraw. 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.endDrawis 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
Groupto aRenderTexture. 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 fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.RenderTexture.fillwould 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.erasehas 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.colorproperty is an instance of the Color object that controls the color value of the light. - The
PointLight.intensityproperty sets the intensity of the light. The colors of the light are multiplied by this value during rendering. - The
PointLight.attenuationproperty sets the attenuation of the light, which is the force with which the light falls off from its center. - The
PointLight.radiusproperty 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.Meshis 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.Vertexis a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.Geom.Mesh.Faceis a new class that consists of references to the threeVertexinstances that construct a single Face in a Mesh and provides methods for manipulating them.Geom.Mesh.GenerateVertsis a new function that will return an array ofVertexandFaceobjects 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.GenerateGridVertsis a new function that will generate a series ofVertexobjects in a grid format, based on the givenGenerateGridConfigconfig 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.GenerateObjVertsis a new function that will generate a series ofVertexobjects 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.ParseObjis a new function that will parse a triangulated Wavefront OBJ file into model data into a format that theGenerateObjVertsfunction can consume.Geom.Mesh.ParseObjMaterialis 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.RotateFaceis a new function that will rotate a Face by a given amount, based on an optional center of rotation.Loader.OBJFileis 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
MeshFactorysignatures have changed toscene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first.indiciesis a new parameter that allows you to provide indexed vertex data to create the Mesh from, where theindiciesarray holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. Theindiciesarray is optional. If your data is not indexed, then simply passnullor an empty array for this parameter. - The
MeshGame 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.addVerticesis 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.addVerticesFromObjis a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the newOBJFilewith athis.load.objcall, 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.hideCCWis 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.modelPositionis a new Vector3 property that allows you to translate the position of all vertices in the Mesh.Mesh.modelRotationis a new Vector3 property that allows you to rotate all vertices in the Mesh.Mesh.modelScaleis a new Vector3 property that allows you to scale all vertices in the Mesh.Mesh.panXis a new function that will translate the view position of the Mesh on the x axis.Mesh.panYis a new function that will translate the view position of the Mesh on the y axis.Mesh.panZis a new function that will translate the view position of the Mesh on the z axis.Mesh.setPerspectiveis a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.Mesh.setOrthois a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.Mesh.clearis a new method that will destroy all Faces and Vertices and clear the Mesh.Mesh.depthSortis a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.Mesh.addVertexis a new method that allows you to add a new single Vertex into the Mesh.Mesh.addFaceis a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.Mesh.getFaceCountnew is a new method that will return the total number of Faces in the Mesh.Mesh.getVertexCountnew is a new method that will return the total number of Vertices in the Mesh.Mesh.getFacenew is a new method that will return a Face instance from the Mesh based on the given index.Mesh.getFaceAtnew 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.verticesis now an array ofGameObject.Vertexinstances, not a Float32Array.Mesh.facesis a new array ofGameObject.Faceinstances, which is populated during a call to methods likeaddVerticesoraddModel.Mesh.totalRenderedis a new property that holds the total number of Faces that were rendered in the previous frame.Mesh.setDebugis 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
BringToTopto 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
MeshGame Object now extends theSingleAlphacomponent 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 standardsetAlphamethods. 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
colorsparameter in the constructor, factory method andaddVerticesmethod. 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
alphasparameter in the constructor, factory method andaddVerticesmethod. If a number, instead of an array, it will be used as the alpha for all vertices created. Mesh.debugGraphicis a new property that holds the debug Graphics instance reference.Mesh.debugCallbackis a new property that holds the debug render callback.Mesh.renderDebugVertsis a new method that acts as the default render callback forsetDebugif none is provided.Mesh.preDestroyis a new method that will clean-up the Mesh arrays and debug references on destruction.Mesh.isDirtyis a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically inpreUpdateto avoid generating lots of math when nothing has changed.- The
Mesh.uvarray has been removed. All UV data is now bound in the Vertex instances. - The
Mesh.colorsarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.alphasarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.tintFillproperty is now abooleanand defaults tofalse.
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.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycoordinates. The character data includes the code, position, dimensions, and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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
setMaxWidthonDynamicBitmapText, 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
Animationclass no longer extendsEventEmitter, 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_KEYevents have been removed. Instead, please use the new events which all carry theframeKeyparameter, which can be used to handle frame specific events. The only exception to this isANIMATION_COMPLETE_KEY, which is a key specific version of the completion event. ANIMATION_UPDATE_EVENTis a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.ANIMATION_STOP_EVENTis a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of thestopmethods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)- The Game Object
Component.Animationcomponent has been renamed toAnimationStateand has moved namespace. It's now inPhaser.Animationsinstead ofGameObjects.Componentsto help differentiate it from theAnimationclass when browsing the documentation. - The
play,playReverse,playAfterDelay,playAfterRepeatandchainSprite and Animation Component methods can now all take aPhaser.Types.Animations.PlayAnimationConfigconfiguration object, as well as a string, as thekeyparameter. 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.createis 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.generateFrameNumbersis 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.generateFrameNamesis 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,playAfterDelayandplayAfterRepeatwill 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.skipMissedFramesis 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.addMixis 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.getMixis a new method that will return the mix duration between the two given animations.AnimationManager.removeMixis a new method that will remove the mixture between either two animations, or all mixtures for the given animation.AnimationState.removeis a new method that will remove a locally stored Animation instance from a Sprite.AnimationState.getis a new method that will return a locally stored Animation instance from the Sprite.AnimationState.existsis a new method that will check if a locally stored Animation exists on the Sprite.- The internal
AnimationState.removemethod has been renamed toglobalRemove. AnimationState.textureManageris a new property that references the global Texture Manager.AnimationState.animsis a new property that contains locally created Animations in a Custom Map.AnimationState.playandSprite.playno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.AnimationState.playReverseandSprite.playReverseno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.- The
AnimationState.delayedPlaymethod has been renamed toplayAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration. - The
AnimationState.stopOnRepeatmethod has been renamed tostopAfterRepeat - The
AnimationState.getCurrentKeymethod has been renamed togetName. AnimationState.getFrameNameis a new method that will return the key of the current Animation Frame, if an animation has been loaded.AnimationState.playAfterDelayandSprite.playAfterDelayare new methods that will play the given animation after the delay in ms expires.AnimationState.playAfterRepeatandSprite.playAfterRepeatare 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.chainmethod is now available on the Sprite class. - The
AnimationState.stopAfterDelaymethod is now available on the Sprite class. - The
AnimationState.stopAfterRepeatmethod is now available on the Sprite class. - The
AnimationState.stopOnFramemethod is now available on the Sprite class. AnimationManager.createFromAsepriteis 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.AnimationStatenow 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 optionalPlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.- The
PlayAnimationConfig.frameRateproperty lets you optionally override the animation frame rate. - The
PlayAnimationConfig.durationproperty lets you optionally override the animation duration. - The
PlayAnimationConfig.delayproperty lets you optionally override the animation delay. - The
PlayAnimationConfig.repeatproperty lets you optionally override the animation repeat counter. - The
PlayAnimationConfig.repeatDelayproperty lets you optionally override the animation repeat delay value. - The
PlayAnimationConfig.yoyoproperty lets you optionally override the animation yoyo boolean. - The
PlayAnimationConfig.showOnStartproperty lets you optionally override the animation show on start value. - The
PlayAnimationConfig.hideOnCompleteproperty lets you optionally override the animation hide on complete value. - The
PlayAnimationConfig.startFrameproperty lets you optionally set the animation frame to start on. - The
PlayAnimationConfig.timeScaleproperty lets you optionally set the animation time scale factor. AnimationState.delayCounteris a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animationSTARTevents fire. Fix #4426 (thanks @bdaenen)AnimationState.hasStartedis 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.showOnStartis a new boolean property that controls if the Game Object should havesetVisible(true)called on it when the animation starts.AnimationState.hideOnCompleteis a new boolean property that controls if the Game Object should havesetVisible(false)called on it when the animation completes.- The
AnimationState.chainmethod docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does! - The
AnimationState.setDelaymethod has been removed. It never actually worked and you can now perform the same thing by calling eitherplayAfterDelayor setting thedelayproperty in the play config. - The
AnimationState.getDelaymethod has been removed. You can now read thedelayproperty directly. - The
AnimationState.setRepeatmethod has been removed. You can achieve the same thing by setting therepeatproperty in the play config, or adjusting the publicrepeatCounterproperty if the animation has started. AnimationState.handleStartis a new internal private method that handles the animation start process.AnimationState.handleRepeatis a new internal private method that handles the animation repeat process.AnimationState.handleStopis a new internal private method that handles the animation stop process.AnimationState.handleCompleteis a new internal private method that handles the animation complete process.AnimationState.emitEventsis a new internal private method that emits animation events, cutting down on duplicate code.- The
AnimationState.restartmethod has a new optional boolean parameterresetRepeatswhich controls if you want to reset the repeat counter during the restart, or not. Animation.getTotalFramesis a new method that will return the total number of frames in the animation. You can access it viathis.anims.currentAnim.getTotalFramesfrom a Sprite.Animation.calculateDurationis a new method that calculates the duration, frameRate and msPerFrame for a given animation target.- The
BuildGameObjectAnimationfunction now uses thePlayAnimationConfigobject to set the values. Sprite.playReverseis a new method that allows you to play the given animation in reverse on the Sprite.Sprite.playAfterDelayis a new method that allows you to play the given animation on the Sprite after a delay.Sprite.stopis a new method that allows you to stop the current animation on the Sprite.AnimationManager.loadhas been removed as it's no longer required.AnimationManager.staggerPlayhas been fixed so you can now pass in negative stagger values.AnimationManager.staggerPlayhas a new optional boolean parameterstaggerFirst, which allows you to either include or exclude the first child in the stagger calculations.- The
Animation.completeAnimationmethod has been removed as it's no longer required. - The
Animation.loadmethod has been removed as it's no longer required. - The
Animation.setFramemethod has been removed as it's no longer required. - The
Animation.getFirstTickmethod has no longer needs theincludeDelayparameter, as it's handled byAnimationStatenow. - The
Animation.getFramesmethod has a new optional boolean parametersortFrameswhich will run a numeric sort on the frame names after constructing them, if a string-based frame is given. Types.Animations.Animationhas a new boolean propertysortFrames, which lets Phaser numerically sort the generated frames.AnimationState.timeScaleis a new public property that replaces the old private_timeScaleproperty.AnimationState.delayis a new public property that replaces the old private_delayproperty.AnimationState.repeatis a new public property that replaces the old private_repeatproperty.AnimationState.repeatDelayis a new public property that replaces the old private_repeatDelayproperty.AnimationState.yoyois a new public property that replaces the old private_yoyoproperty.AnimationState.inReverseis a new public property that replaces the old private_reverseproperty.AnimationState.startAnimationis a new public method that replaces the old private_startAnimationmethod.- The
AnimationState.getProgressmethod has been fixed so it will return correctly if the animation is playing in reverse. - The
AnimationState.globalRemovemethod will now always be called when an animation is removed from the global Animation Manager, not just once. - The
AnimationState.getRepeatmethod has now been removed. You can get the value from therepeatproperty. - The
AnimationState.setRepeatDelaymethod has now been removed. You can set the value using therepeatDelayconfig property, or changing it at run-time. AnimationState.completeis a new method that handles the completion in animation playback.- The
AnimationState.setTimeScalemethod has now been removed. You can set the value using thetimeScaleconfig property, or changing it at run-time. - The
AnimationState.getTimeScalemethod has now been removed. You can read the value using thetimeScaleproperty. - The
AnimationState.getTotalFramesmethod has been fixed and won't error if called when no animation is loaded. - The
AnimationState.setYoyomethod has now been removed. You can set the value using theyoyoconfig property, or changing it at run-time. - The
AnimationState.getYoyomethod has now been removed. You can read the value using theyoyoproperty. - The
AnimationState.stopAfterRepeatmethod now has an optional parameterrepeatCount, 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.updateFramemethod has now been removed. Everything is handled bysetCurrentFrameinstead, which removes one extra step out of the update process. GenerateFrameNameswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswould include the__BASEframe by mistake in its calculations. This didn't end up in the final animation, but did cause a cache miss when building the animation.GenerateFrameNumberscan now accept thestartandendparameters in reverse order, meaning you can now do{ start: 10, end: 1 }to create the animation in reverse.GenerateFrameNamescan now accept thestartandendparameters 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.createDynamicLayermethod has been renamed tocreateLayer. - The
Tilemap.createStaticLayermethod has been removed. UsecreateLayerinstead. - The
Tilemap.createBlankDynamicLayermethod has been renamed tocreateBlankLayer. - The
Tilemap.convertLayerToStaticmethod has been removed as it is no longer required. - The
TilemapLayerWebGLRendererfunction 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.TilemapOrientationTypeis a new type def that holds the 4 types of map orientation now supported.- The
Tile.updatePixelXYmethod now updates the tile XY position based on map type. ParseTilesetswill now correctly handle non-consecutive tile IDs. It also now correctly sets themaxIdproperty, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)Tilemap.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.LayerData.orientationis a new property that holds the tilemap layers orientation constant.LayerData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.MapData.orientationis a new property that holds the tilemap layers orientation constant.MapData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.Tilemaps.Components.HexagonalWorldToTileYis a new function that converts a world Y coordinate to hexagonal tile Y coordinate.Tilemaps.Components.StaggeredWorldToTileYis a new function that converts a world Y coordinate to staggered tile Y coordinate.Tilemaps.Components.HexagonalWorldToTileXYis a new function that converts world coordinates to hexagonal tile coordinates.Tilemaps.Components.IsometricWorldToTileXYis a new function that converts world coordinates to isometric tile coordinates.Tilemaps.Components.StaggeredWorldToTileXYis a new function that converts world coordinates to staggered tile coordinates.Tilemaps.Components.HexagonalTileToWorldYis a new function that converts a hexagonal Y coordinate to a world coordinate.Tilemaps.Components.StaggeredTileToWorldYis a new function that converts a staggered Y coordinate to a world coordinate.Tilemaps.Components.HexagonalTileToWorldXYis a new function that converts hexagonal tile coordinates to world coordinates.Tilemaps.Components.IsometricTileToWorldXYis a new function that converts isometric tile coordinates to world coordinates.Tilemaps.Components.StaggeredTileToWorldXYis a new function that converts staggered tile coordinates to world coordinates.Tilemaps.Components.GetTileToWorldXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldXXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetCullTilesFunctionis a new function that returns the correct culling function to use.Tilemaps.Components.HexagonalCullTilesis a new function that culls tiles in a hexagonal map.Tilemaps.Components.StaggeredCullTilesis a new function that culls tiles in a staggered map.Tilemaps.Components.IsometricCullTilesis a new function that culls tiles in a isometric map.Tilemaps.Components.CullBoundsis a new function that calculates the cull bounds for an orthogonal map.Tilemaps.Components.HexagonalCullBoundsis a new function that calculates the cull bounds for a hexagonal map.Tilemaps.Components.StaggeredCullBoundsis a new function that calculates the cull bounds for a staggered map.Tilemaps.Components.RunCullis a new function that runs the culling process from the combined bounds and tilemap.Tilemap._convertis a new internal private hash of tilemap conversion functions used by the public API.- The
Tilemap._isStaticCallmethod 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
GetTilesWithinWorldXYcomponent directly, saving lots of overhead. - The method
Tilemap.weightedRandomizehas changed so that the parameterweightedIndexesis now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional. - The method
TilemapLayer.weightedRandomizehas changed so that the parameterweightedIndexesis 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_SCENEis 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_SCENEis 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_SCENEis 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_SCENEis 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.addedToSceneis 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.removedFromSceneis 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 theremovedFromScenemethod now. - The
Containerwill 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.eventsis a new property that references the Scene's Event Emitter. This is now used internally.DisplayList.addChildCallbackis a new method that overrides the List callback and fires the new ADDED events.DisplayList.removeChildCallbackis a new method that overrides the List callback and fires the new REMOVED events.GameObjectCreator.eventsis a new property that references the Scene's Event Emitter. This is now used internally.GameObjectFactory.eventsis a new property that references the Scene's Event Emitter. This is now used internally.ProcessQueue.checkQueueis a new boolean property that will make sure only unique objects are added to the Process Queue.- The
Update Listnow uses the newcheckQueueproperty to ensure no duplicate objects are on the active list. DOMElementFactory,ExternFactory,ParticleManagerFactor,RopeFactoryandSpriteFactoryall no longer add the objects to the Update List, this is now handled by the ADDED events instead.Sprite,Rope,ParticleEmitterManager,ExternandDOMElementnow all override theaddedToSceneandremovedFromScenecallbacks to handle further set-up tasks.
Input Manager and Mouse Manager - New Features, API Changes and Bug Fixes
ScaleManager.refreshis now called when theGame.READYevent 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
inputMouseCapturehas been removed, as this is now split into 3 new config options: inputMousePreventDefaultDownis a new config option that allows you to controlpreventDefaultcalls specifically on mouse down events. Set it viainput.mouse.preventDefaultDownin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultUpis a new config option that allows you to controlpreventDefaultcalls specifically on mouse up events. Set it viainput.mouse.preventDefaultUpin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultMoveis a new config option that allows you to controlpreventDefaultcalls specifically on mouse move events. Set it viainput.mouse.preventDefaultMovein the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultWheelis a new config option that allows you to controlpreventDefaultcalls specifically on mouse wheel events. Set it viainput.mouse.preventDefaultWheelin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.- The
MouseManager.captureproperty has been removed, as this is now split into 3 new config options (see below) MouseManager.preventDefaultDownis a new boolean property, set via theinputMousePreventDefaultDownconfig option that allows you to toggle capture of mouse down events at runtime.MouseManager.preventDefaultUpis a new boolean property, set via theinputMousePreventDefaultUpconfig option that allows you to toggle capture of mouse up events at runtime.MouseManager.preventDefaultMoveis a new boolean property, set via theinputMousePreventDefaultMoveconfig option that allows you to toggle capture of mouse move events at runtime.MouseManager.preventDefaultWheelis a new boolean property, set via theinputMousePreventDefaultWheelconfig option that allows you to toggle capture of mouse wheel at runtime.- In the
MouseManagerthe 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
GamepadPluginwill now callrefreshPadsas 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 viathis.input.gamepad.pad1and 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._createdis 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.downwill 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
useHandCursorenabled, 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.shutdownmethod 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.processOverEventshas 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.tintTopLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTLwhich has now been removed.Tint.tintTopRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTRwhich has now been removed.Tint.tintBottomLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBLwhich has now been removed.Tint.tintBottomRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBRwhich has now been removed.- The property
Tint._isTintedhas been removed as it's no longer required. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they now read the color value asoutTint.bgrinstead ofoutTint.rgb. This allows the colors to remain in RGB order within the Tint component. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they no longer have a 3-way check on theoutTintEffectvalue. - The
Multi Pipeline,Bitmap Text,Render Texture,Text,TileSpriteandCameranow all read the tint values from the public properties instead of the private_tintTLetc ones. They also now set thetintEffectvalue directly from thetintFillproperty, removing another conditional check. - The function
GetColorFromValuehas been removed as it's no longer used internally. - The
Rope.tintFillproperty is now a boolean, not an integer, and can no longer take2as 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
getTintAppendFloatAlphaAndSwaphave been replaced withgetTintAppendFloatAlphainstead. - As a result of the change to the shader, the Multi Pipeline now uses the
WebGLRenderer.whiteTextureandtintEffectmode 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.whiteTextureis 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
TextureManagernow generates a new texture with the key__WHITEduring its boot process. This is a pure white 4x4 texture used by the Graphics pipelines. Config.images.whiteis 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
Bodyclass has a new boolean propertypushable(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.setPushableis a new chainable method that allows you to set thepushablestate of a Body.Arcade.Components.Pushableis 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.disableUpdateis a new method that will prevent the Arcade Physics Worldupdatemethod 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.enableUpdateis 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.customUpdateis a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. Iftruethe World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)Physics.Arcade.Body.setCollideWorldBoundsnow has a new optional parameteronWorldBoundswhich allows you to enable the Body'sonWorldBoundsproperty in the same call (thanks @samme)ArcadePhysics.Body.setMaxVelocityXis a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)ArcadePhysics.Body.setMaxVelocityYis a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)- The
PhysicsGroupconfig now has two new optional propertiesmaxVelocityXandmaxVelocityYwhich allows you to set the maximum velocity on bodies added to the Group (thanks @samme) - The
Arcade.Body.resetFlagsmethod has a new optional boolean parameterclear. If set, it clears thewasTouchingflags on the Body. This happens automatically whenBody.resetis called. Previous to this, the flags were not reset until the next physics step (thanks @samme) Physics.Arcade.ProcessXis a new set of functions, called by theSeparateXfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Physics.Arcade.ProcessYis a new set of functions, called by theSeparateYfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Arcade.Body.centervalues 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_STEPevent now has a new parameter: the delta argument (thanks @samme) - The Arcade Body
dragproperty 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 usedragyou will need to change any existing drag values to get the same effects as before. Convertdragtodrag ^ 60ordrag ^ fpsif you use a different step rate (thanks @samme)
New Features
Geom.Intersects.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Intersects.GetLineToPointsis 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.GetRaysFromPointToPolygonis 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.Translateis a new function that allows you to translate all the points of a polygon by the given values.Geom.Polygon.Simplifyis 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.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.getTweensOfhas a new parameterincludePending. 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.hasBootedis 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 theWebGLRenderer.addPipelinemethod, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)- The WebGL Renderer will now add the pipelines during the
bootmethod, instead ofinit. - You can now use
this.rendererfrom within a Scene, as it's now a Scene-level property and part of the Injection Map. Clock.addEventcan now take an existingTimerEventobject, as well as a config object. If aTimerEventis 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.removeEventis a new method that allows you to remove aTimerEvent, or an array of them, from all internal lists of the current Clock.Group.getMatchingis a new method that will return any members of the Group that match the given criteria, such asgetMatching('visible', true)(thanks @atursams)Utils.Array.SortByDigitsis 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 callingGroup.createMultipleorGroup.createFromConfig, can now accept the following new properties:setOrigin: { x, y, stepX, stepY }which are applied to the items created by the Group.Transform.copyPositionis a new method that will copy the position from the given object to the Game Object (thanks @samme)- The
Text.MeasureTextfunction, 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 newactualBoundingBoxAscentfunctions 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.GetCalcMatrixis 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,StarandTriangle. This dramatically reduces the amount of duplicate code across the API.Utils.Array.Matrix.Translateis a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.Vertor3.addScaleis 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
easeParamsin the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh) BitmapMask.createMaskis 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.clearMaskwill 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.Quaternionnow has a new propertyonChangeCallbackwhich, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.- The
Quaternion.setmethod has a new optional boolean parameterupdate(defaults totrue), which will call theonChangeCallbackif set. Quaternion.setFromEuleris a new method that will set the quaternion from the givenEulerobject, optionally calling theonChangeCallbackin the process.Quaternion.setFromRotationMatrixis a new method that will set the rotation of the quaternion from the given Matrix4.Vector3.setFromMatrixPositionis a new method that will set the components of the Vector3 based on the position of the given Matrix4.Vector3.setFromMatrixColumnis a new method that will set the components of the Vector3 based on the specified Matrix4 column.Vector3.fromArrayis a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.Vector3.minis a new method that will set the components of the Vector3 based on theMain.minbetween it and the given Vector3.Vector3.maxis a new method that will set the components of the Vector3 based on theMain.maxbetween it and the given Vector3.Vector3.addVectorsis a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.Vector3.addScalaris a new method that will multiply the components of the Vector3 by the scale value given.Vector3.applyMatrix3is a new method that will take a Matrix3 and apply it to the Vector3.Vector3.applyMatrix4is a new method that will take a Matrix4 and apply it to the Vector3.Vector3.projectViewMatrixis a new method that multiplies the Vector3 by the given view and projection matrices.Vector3.unprojectViewMatrixis a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.Matrix4.setValuesis a new method that allows you to set all of the matrix components individually. Most internal methods now use this.Matrix.multiplyToMat4is a new method that multiplies a Matrix4 by the givensrcMatrix4 and stores the results in theoutMatrix4.Matrix4.fromRotationXYTranslationis a new method that takes the rotation and position vectors and builds this Matrix4 from them.Matrix4.getMaxScaleOnAxisis a new method that will return the maximum axis scale from the Matrix4.Matrix4.lookAtRHis a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.Matrix4.transformis a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.Matrix4.multiplyMatricesis a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.Matrix4.premultiplyis a new method that takes a Matrix4 and multiplies it by the current Matrix4.Matrix4.getInverseis a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.CameraManager.getVisibleChildrenis a new method that is called internally by theCameraManager.rendermethod. It filters the DisplayList, so that Game Objects that pass thewillRendertest 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.setDampingis a new method that allows you to set theuseDampingproperty of a Body in a chainable way. Fix #5352 (thanks @juanitogan)- The
GameObjects.Graphics.fillGradientStylemethod 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.PipelineConfigis a new configuration object that you can set in the Game Config under thepipelineproperty. 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 thepipelineobject, or set it under therendersub-config.Utils.Object.DeepCopyis a new function that will recursively deep copy an array of object.Time.TimerEvent.getRemainingis a new method that returns the time interval until the next iteration of the Timer Event (thanks @samme)Time.TimerEvent.getRemainingSecondsis a new method that returns the time interval until the next iteration of the Timer Event in seconds (thanks @samme)Time.TimerEvent.getOverallRemainingis a new method that returns the time interval until the last iteration of the Timer Event (thanks @samme)Time.TimerEvent.getOverallRemainingSecondsis a new method that returns the time interval until the last iteration of the Timer Event in seconds (thanks @samme)GameObjects.Video.loadMediaStreamis 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.ColorSpectrumis 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.AsepriteFileis 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 viathis.load.asesprite(png, json).GameObject.displayListis 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
ShaderGame Object now supports being able to use a Render Texture as asampler2Dtexture on the shader #5423 (thanks @ccaleb) BaseSound.pan,HTMLAudioSound.panandWebAudioSound.panare 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.setPanis 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.PANis a new event dispatched by both Web Audio and HTML5 Audio Sound objects when their pan changes (thanks @pi-kei)
ColorMatrix
Phaser.Display.ColorMatrixis 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.setmethod allows you to set the values of a ColorMatrix. - The
ColorMatrix.resetmethod will reset the ColorMatrix to its default values. - The
ColorMatrix.getDatamethod will return the data in the ColorMatrix as a Float32Array, useful for setting in a shader uniform. - The
ColorMatrix.brightnessmethod lets you set the brightness of the ColorMatrix. - The
ColorMatrix.saturatemethod lets you set the saturation of the ColorMatrix. - The
ColorMatrix.desaturatemethod lets you desaturate the colors in the ColorMatrix. - The
ColorMatrix.huemethod lets you rotate the hues of the ColorMatrix by the given amount. - The
ColorMatrix.grayscalemethod converts the ColorMatrix to grayscale. - The
ColorMatrix.blackWhitemethod converts the ColorMatrix to black and whites. - The
ColorMatrix.contrastmethod lets you set the contrast of the ColorMatrix. - The
ColorMatrix.negativemethod converts the ColorMatrix to negative values. - The
ColorMatrix.desaturateLuminancemethod applies a desaturated luminance to the ColorMatrix. - The
ColorMatrix.sepiamethod applies a sepia tone to the ColorMatrix. - The
ColorMatrix.nightmethod applies a night time effect to the ColorMatrix. - The
ColorMatrix.lsdmethod applies a trippy color effect to the ColorMatrix. - The
ColorMatrix.brownmethod applies a brown tone to the ColorMatrix. - The
ColorMatrix.vintagePinholemethod applies a vintage pinhole color effect to the ColorMatrix. - The
ColorMatrix.kodachromemethod applies a kodachrome color effect to the ColorMatrix. - The
ColorMatrix.technicolormethod applies a technicolor color effect to the ColorMatrix. - The
ColorMatrix.polaroidmethod applies a polaroid color effect to the ColorMatrix. - The
ColorMatrix.shiftToBGRmethod shifts the values of the ColorMatrix into BGR order. - The
ColorMatrix.multiplymethod 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.Earcutand is fully documented. Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself. - The constant
Phaser.Renderer.WebGL.BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.FLOATvalue has been removed as it wasn't used internally. Pointer.downTimenow 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.upTimenow 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.getDurationmethod now uses the new PointerdownTimeandupTimevalues, 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
BaseShaderdefault vertex shader now includes theoutTexCoordvec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok) - When using the
GameObjectCreatorforContainersyou can now specify thechildrenproperty in the configuration object. Textures.Parsers.JSONHashwill now perform ahasOwnPropertycheck when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes fromJSON.parse. Fix #4768 (thanks @RollinSafary)- The
Camera3DPlugin 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.seekwill 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
inputWindowEventsis set in the Game Config, then theMouseManagerwill now listen for the events onwindow.topinstead of justwindow, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in atry/catchblock, as not all sites allow access towindow.top(specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow) MouseManager.isTopis a new boolean read-only property that flags if the mouse event listeners were attached towindow.top(true), or justwindow(false). By default Phaser will attemptwindow.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back towindowin those cases and set this property to false (thanks BunBunBun)Types.GameObjects.Text.GetTextSizeObjectis a new type def for the GetTextSize function results.Utils.Array.StableSorthas 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. Theinplacefunction has been removed, just callStableSort(array)directly now. All classes that usedStableSort.inplacehave 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.setOriginwill now callupdateDisplayOriginon the items array, otherwise the effects can't be seen when rendering.- You can now set the
ArcadeWorld.fixedStepproperty via theArcadeWorldConfigobject (thanks @samme) Utils.Array.NumerArraycan now accept thestartandendparameters in reverse order, i.e.10, 1will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.DataManager.Events.DESTROYis a new event that the Data Manager will listen for from its parent and then call its owndestroymethod when received.- The
Quaternionclass constructor will now default the values to0,0,0,1if they're not provided, making it an identity quaternion, rather than the0,0,0,0it was before. - You can now set the
ParticleEmitter.reservevalue via the emitter configuration object (thanks @vforsh) - Setting the
pixelArtconfig option will now setantialiasGLtofalse, as well asantialias. Fix #5309 (thanks @Vegita2) - The
Shapeclass now includes theComputedSizecomponent properties and methods directly in the class, rather than applying as a mixin.setSizeis now flagged as beingprivate, 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.maxParallelDownloadsvalue is now set to 6 if running on Android, or 32 on any other OS. This avoidsnet::ERR_FAILEDissues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary) - When running an Arcade Physics
overlaptest against aStaticBody, it will no longer set theblockedstates 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
LineGame 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
Quaternionclass now has 4 new private properties:_x,_y,_zand_wand 4 new getters and setters for the public versions. It also now passes most methods viasetto allow for the onChange callback to be invoked. This does not change the public-facing API. Groupnow extendsEventEmitter, allowing you to emit custom events from within a Group.Device.Audio.wavnow usesaudio/wavas thecanPlayTypecheck string, instead ofaudio/wav; codecs="1", which should allow iOS13 to play wav files again.- In the
Loader.FileTypes.TextFileconfig you can now override the type and cache destination for the file. Loader.MultiFilewill 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.tintvalue is now0xffffff(previously, it was0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh) SceneManager.startwill now reset theSceneSystems.sceneUpdatereference toNOOP. This gets set back to the Scene update method again duringbootScene(if it has one) and stops errors with external plugins and multi-part files that may triggerupdatebeforecreatehas been called. Fix #4629 (thanks @Osmose)Phaser.Scene.rendereris a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.- The
CanvasRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead. - Since iOS 13, iPads now identify as MacOS devices. A new maxTouchPoint check is now part of the
Device.OStests, stopping iPads from being flagged as desktop devices. Fix #5389 (thanks @SBCGames) - The
BitmapMask.prevFramebufferproperty has been removed as it's no longer required, due to the fbo stack in the renderer. - The
TextureManager.addGLTexturemethod has been updated so that thewidthandheightparameters are now optional. If not provided, and if available, they will be read from the given WebGLTexture instead (thanks @hexus) GameObjects.Components.Depth.depthListis 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
WebAudioSoundManagerwill no longer try to unlock itself if the Game hasn't already booted and been added to the DOM. It will now wait for theBOOTevent and unlock based on that. Fix #5439 (thanks @samme)
Bug Fixes
- The
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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
ProcessQueuewas emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar) - The
GridAlignaction didn't work if only theheightparameter was set. Fix #5019 (thanks @halilcakar) - The
Color.HSVToRGBfunction has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX) - Previously, the
easeParamsarray within a Tweenspropsobject, 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.setRenderToTextureitszoomandrotationvalues would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok) GameObjects.Shape.Gridwould render a white fill even if you passedundefinedas the fill color in the constructor. It now doesn't render cells if no fill color is given.- The
onMouseevents in the Input Manager didn't reset theactivePointerproperty 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
GetScreenOrientationfunction will now check forwindow.orientationfirst, 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 emitorientationchangeevents correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu) Time.Clock.addEventcan now take an instance of aTimerEventas its parameter. Fix #5294 (thanks @samme @EmilSV)GameConfig.audionow defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)- The
Loader.pathwas 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.getMatchingwould always return an empty array. It now returns matching children (thanks @samme)- The
ParticleManagerWebGLRenderernow 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
ParticleManagerCanvasRenderernow calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also usessetToContextinternally. 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
GraphicsWebGL Renderer will now default topathOpen = true. This fixes issues under WebGL where, for example, adding an arc and callingstrokePath, without first callingbeginPathwill no longer cause rendering artefacts when WebGL tries to close the path with a single tri. Graphics.strokeRoundedRectnow issuesmoveTocommands 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
snapshotin WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in theWebGLSnapshotfunction. Fix #4956 (thanks @gammafp @telinc1) Particles.EmitterOp.setMethodswill now reset bothonEmitandonUpdateto 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.EmitterOpnow cleanly separates between the different types of property configuration options.start | endwill now ease between the two values,min | maxwill pick a random value between them andrandom: []will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)- When setting both
transparent: trueandbackgroundColorin 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
EllipseGame Object now will update the width, height, and geometric position in thesetSizemethod (thanks @PhaserEditor2D) - When measuring the last word in a line in a
TextGame Object, it no longer adds extra white space to the end (thanks @rexrainbow) Utils.Array.Removewould 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.TriangleToLinewouldn't returntrueif 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)
BitmapMaskwould 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.
AtlasJSONFileno longer stores the JSON in the JSON Cache once the texture has been created.AtlasXMLFileno longer stores the XML in the XML Cache once the texture has been created.UnityAtlasFileno longer stores the Text in the Text Cache once the texture has been created.BitmapFontFileno longer stores the XML in the XML Cache once the texture has been created.- You can now use
TextureManager.removeto 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.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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#RESIZEevent no longer sends theresolutionas a parameter. - The
BaseCamera.resolutionproperty has been removed. - The internal private
BaseCamera._cx,_cy,_cwand_chproperties has been removed, usex,y,widthandheightinstead. - The
BaseCamera.preRendermethod no longer receives or uses theresolutionparameter. - The
Camera.preRendermethod no longer receives or uses theresolutionparameter. - The
CameraManager.onResizemethod no longer receives or uses theresolutionparameter. - The
Core.Config.resolutionproperty has been removed. - The
TextStyle.resolutionproperty 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
CanvasRendererno longer reads or uses the Game Config resolution property. - The
PipelineManager.resizemethod along withWebGLPipeline.resizeand anything else that extends them no longer receives or uses theresolutionparameter. - The
WebGLRenderer.resizeandonResizemethods no longer receives or uses theresolutionparameter. - The
ScaleManager.resolutionproperty 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.MoveTofunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.DOM.GetInnerHeightfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Bobclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsManagerclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsPluginclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Particles.EmitterOpclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.GetTextSizefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.MeasureTextfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.TextStylefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Input.CreatePixelPerfectHandlerfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapCircfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapRectfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Tilemapnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Componentsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.MatterGameObjectclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.PointerConstraintclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetPhysicsPluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetScenePluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Structs.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Tilemaps.Parsers.Tiledfunction has now been exposed on the Phaser namespace (thanks @samme) - Every single
Tilemap.Componentfunction 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:
TextureTintPipelineis now called theMultiPipeline.TextureTintStripPipelineis now called theRopePipeline.ForwardDiffuseLightPipelineis now called theLightPipeline.
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.fragis now calledLight.frag.TextureTint.fragis now calledMulti.frag.TextureTint.vertis now calledMulti.vert.
Other pipeline changes are as follows:
- None of the shaders or pipelines use the
uViewMatrixanduModelMatrixuniforms 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.WebGLPipelineConfigis a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.Types.Renderer.WebGL.WebGLPipelineAttributesConfigis 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
rendererproperty automatically, so it's no longer required in the config. - All pipelines will now work out the
glproperty automatically, so it's no longer required in the config. - All pipelines will now extract the
nameproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexCapacityproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexSizeproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexDataproperty from the config, allowing you to set it externally. - All pipelines will now extract the
attributesproperty from the config, allowing you to set it externally. - All pipelines will now extract the
topologyproperty from the config, allowing you to set it externally. - The
WebGLPipeline.shouldFlushmethod now accepts an optional parameteramount. If given, it will returntrueif 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
RopePipelinenow extendsMultiPipelineand just changes the topolgy, vastly reducing the filesize. - The
WebGLPipeline.flushLockedproperty 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.setPipelinemethod, 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.set1fwill set a 1f uniform based on the given name.WebGLPipeline.set2fwill set a 2f uniform based on the given name.WebGLPipeline.set3fwill set a 3f uniform based on the given name.WebGLPipeline.set4fwill set a 4f uniform based on the given name.WebGLPipeline.set1fvwill set a 1fv uniform based on the given name.WebGLPipeline.set2fvwill set a 2fv uniform based on the given name.WebGLPipeline.set3fvwill set a 3fv uniform based on the given name.WebGLPipeline.set4fvwill set a 4fv uniform based on the given name.WebGLPipeline.set1ivwill set a 1iv uniform based on the given name.WebGLPipeline.set2ivwill set a 2iv uniform based on the given name.WebGLPipeline.set3ivwill set a 3iv uniform based on the given name.WebGLPipeline.set4ivwill set a 4iv uniform based on the given name.WebGLPipeline.set1iwill set a 1i uniform based on the given name.WebGLPipeline.set2iwill set a 2i uniform based on the given name.WebGLPipeline.set3iwill set a 3i uniform based on the given name.WebGLPipeline.set4iwill set a 4i uniform based on the given name.WebGLPipeline.setMatrix2fvwill set a matrix 2fv uniform based on the given name.WebGLPipeline.setMatrix3fvwill set a matrix 3fv uniform based on the given name.WebGLPipeline.setMatrix4fvwill 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.setFloat1has been removed. Please useset1finstead.WebGLPipeline.setFloat2has been removed. Please useset2finstead.WebGLPipeline.setFloat3has been removed. Please useset3finstead.WebGLPipeline.setFloat4has been removed. Please useset4finstead.WebGLPipeline.setFloat1vhas been removed. Please useset1fvinstead.WebGLPipeline.setFloat2vhas been removed. Please useset2fvinstead.WebGLPipeline.setFloat3vhas been removed. Please useset3fvinstead.WebGLPipeline.setFloat4vhas been removed. Please useset4fvinstead.WebGLPipeline.setInt1has been removed. Please useset1iinstead.WebGLPipeline.setInt2has been removed. Please useset2iinstead.WebGLPipeline.setInt3has been removed. Please useset3iinstead.WebGLPipeline.setInt4has been removed. Please useset4iinstead.WebGLPipeline.setMatrix1has been removed. Please usesetMatrix2fvinstead.WebGLPipeline.setMatrix2has been removed. Please usesetMatrix3fvinstead.WebGLPipeline.setMatrix3has been removed. Please usesetMatrix4fvinstead.
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.pipelinesis no longer a plain object containing pipeline instances. It's now an instance of thePipelineManagerclass. This instance is created during the init and boot phase of the renderer.- The
WebGLRenderer.currentPipelineproperty no longer exists, instead usePipelineManager.current. - The
WebGLRenderer.previousPipelineproperty no longer exists, instead usePipelineManager.previous. - The
WebGLRenderer.hasPipelinemethod no longer exists, instead usePipelineManager.has. - The
WebGLRenderer.getPipelinemethod no longer exists, instead usePipelineManager.get. - The
WebGLRenderer.removePipelinemethod no longer exists, instead usePipelineManager.remove. - The
WebGLRenderer.addPipelinemethod no longer exists, instead usePipelineManager.add. - The
WebGLRenderer.setPipelinemethod no longer exists, instead usePipelineManager.set. - The
WebGLRenderer.rebindPipelinemethod no longer exists, instead usePipelineManager.rebind. - The
WebGLRenderer.clearPipelinemethod no longer exists, instead usePipelineManager.clear.
The Pipeline Manager also offers the following new features:
- The
PipelineManager.resizemethod automatically handles resize events across all pipelines. - The
PipelineManager.preRendermethod calls the pre-render method of all pipelines. - The
PipelineManager.rendermethod calls the render method of all pipelines. - The
PipelineManager.postRendermethod calls the post-render method of all pipelines. - The
PipelineManager.setMultimethod automatically binds the Multi Texture Pipeline, Phaser's default. - The
PipelineManager.clearmethod will clear the pipeline, store it inpreviousand free the renderer. - The
PipelineManager.rebindmethod will reset the rendering context and restore thepreviouspipeline, if set.
New constants have been created to help you reference a pipeline without needing to use strings:
Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINEfor the Bitmap Mask Pipeline.Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINEfor the Light 2D Pipeline.Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINEfor the Single Pipeline.Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINEfor the Multi Pipeline.Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINEfor 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture that was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLPipeline.forceZerois a new property that informs Game Objects if the pipeline requires a zero bound texture unit.WebGLPipeline.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLRenderer.unbindTexturesis a new method that will activate and then null bind all WebGL textures.Renderer.WebGL.Utils.parseFragmentShaderMaxTexturesis 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.getComponentCountfunction has been removed as this is no longer required internally.
WebGLRenderer New Features, Updates and API Changes
WebGLRenderer.instancedArraysExtensionis a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.WebGLRenderer.vaoExtensionis a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.WebGLRenderer.resetProgramis a new method that will rebind the current program, without flushing or changing any properties.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.WebGLRenderer.finalTypeis a new boolean property that signifies if the current Game Object being rendered is the final one in the list.- The
WebGLRenderer.updateCanvasTexturemethod will now setgl.UNPACK_PREMULTIPLY_ALPHA_WEBGLto 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.previousPipelineis a new property that is set during a call toclearPipelineand used during calls torebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.- The
WebGLRenderer.rebindPipelinemethod has been changed slightly. Previously, you had to specify thepipelineInstance, but this is now optional. If you don't, it will use the newpreviousPipelineproperty instead. If not set, or none given, it will now return without throwing gl errors as well. WebGLRenderer.defaultScissoris a new property that holds the default scissor dimensions for the renderer. This is modified duringresizeand avoids continuous array generation in thepreRenderloop.- The
WebGLRenderer.nativeTexturesarray has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in theTextureSourceobjects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy. - The
WebGLRenderer.deleteTexturemethod has a new optional boolean parameterresetwhich allows you to control if theWebGLRenderer.resetTexturesmethod is called, or not, after the texture is deleted. - The
WebGLRenderer.getMaxTexturesmethod has been removed. This is no longer needed as you can use theWebGLRenderer.maxTexturesproperty instead. - The
WebGLRenderer.setProgrammethod now returns a boolean.trueif the program was set, otherwisefalse. - The
WebGLRenderer.setVertexBuffermethod now returns a boolean.trueif the buffer was set, otherwisefalse. WebGLRenderer.setFloat1has been removed. UseWebGLPipeline.set1forWebGLShader.set1finstead.WebGLRenderer.setFloat2has been removed. UseWebGLPipeline.set2forWebGLShader.set2finstead.WebGLRenderer.setFloat3has been removed. UseWebGLPipeline.set3forWebGLShader.set3finstead.WebGLRenderer.setFloat4has been removed. UseWebGLPipeline.set4forWebGLShader.set4finstead.WebGLRenderer.setFloat1vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set1fvinstead.WebGLRenderer.setFloat2vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set2fvinstead.WebGLRenderer.setFloat3vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set3fvinstead.WebGLRenderer.setFloat4vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set4fvinstead.WebGLRenderer.setInt1has been removed. UseWebGLPipeline.set1fiorWebGLShader.set1iinstead.WebGLRenderer.setInt2has been removed. UseWebGLPipeline.set1fiorWebGLShader.set2iinstead.WebGLRenderer.setInt3has been removed. UseWebGLPipeline.set1fiorWebGLShader.set3iinstead.WebGLRenderer.setInt4has been removed. UseWebGLPipeline.set1fiorWebGLShader.set4iinstead.WebGLRenderer.setMatrix2has been removed. UseWebGLPipeline.setMatrix2fvorWebGLShader.setMatrix2fvinstead.WebGLRenderer.setMatrix3has been removed. UseWebGLPipeline.setMatrix3fvorWebGLShader.setMatrix3fvinstead.WebGLRenderer.setMatrix4has been removed. UseWebGLPipeline.setMatrix4fvorWebGLShader.setMatrix4fvinstead.- The
WebGLRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead. WebGLRenderer.fboStackis a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.WebGLRenderer.pushFramebufferis 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 ofsetFramebuffer. Remember to callpopFramebufferafter using it.WebGLRenderer.popFramebufferis a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.WebGLRenderer.setFramebufferhas a new optional boolean parameterresetTextureswhich will reset the WebGL Textures, if set totrue(which is the default).WebGLRenderer.isBootedis a new boolean property that lets you know if the rendere has fully finished booting.- The
WebGLRenderernow extends the Event Emitter, allowing you to listen to renderer specific events. Phaser.Renderer.WebGL.Eventsis a new WebGL Renderer namespace for events.WebGL.Events.PRE_RENDERis a new event dispatched by the WebGL Renderer. This happens right at the start of the render process.WebGL.Events.RENDERis 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_RENDERis a new event dispatched by the WebGL Renderer. This happens right at the end of the render process.WebGL.Events.RESIZEis 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.renderToTextureproperty has been removed. Effects are now handled via pipelines. - The
Camera.renderToGameproperty has been removed. Effects are now handled via pipelines. - The
Camera.canvasproperty has been removed. Textures are handled by pipelines. - The
Camera.contextproperty has been removed. Textures are handled by pipelines. - The
Camera.glTextureproperty has been removed. GL Textures are handled by pipelines. - The
Camera.framebufferproperty has been removed. GL Framebuffers are handled by pipelines. - The
Camera.setRenderToTexturemethod has been removed. Effects are now handled via pipelines. - The
Camera.clearRenderToTexturemethod 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.zoomXis a new property that allows you to specifically set the horizontal zoom factor of a Camera.Camera.zoomYis a new property that allows you to specifically set the vertical zoom factor of a Camera.- The
Camera.setZoommethod now allows you to pass two parameters:xandy, to control thezoomXandzoomYvalues accordingly. - The
Camera.zoomproperty now returns an average of thezoomXandzoomYproperties. Cameras.Scene2D.Events.FOLLOW_UPDATEis 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
roundPixelsset it will now round the internal scroll factors andworldViewduring thepreRenderstep. 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 (
inPositionandinColor), 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
calcMatrixproperty has been added, which Shape Game Objects use to maintain transform state during rendering. - The Graphics Pipeline no longer makes use of
tintEffector 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.setTexturehas 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.renderWebGLnow uses the standardGetCalcMatrixfunction, 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.renderTargetis a new property that contains aRenderTargetinstance, which is used for all drawing.- The
RenderTexture.framebufferproperty has been removed. You can now access this viaRenderTexture.renderTarget.framebuffer. - The
RenderTexture.glTextureproperty has been removed. You can now access this viaRenderTexture.renderTarget.texture. - The
RenderTexture.glproperty has been removed.
Render Textures have the following new features:
RenderTexture.beginDrawis a new method that allows you to create a batched draw to the Render Texture. Use this method to begin the batch.RenderTexture.batchDrawis 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 withbeginDraw. 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.batchDrawFrameis 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 withbeginDraw. 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.endDrawis 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
Groupto aRenderTexture. 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 fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.RenderTexture.fillwould 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.erasehas 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis a new method that will look-up and return a normal map for the given object.
Lights
Light.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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:
projIdentityhas been removed.projPersphas been removed.modelRotateXhas been removed.modelRotateYhas been removed.modelRotateZhas been removed.viewLoadhas been removed.viewRotateXhas been removed.viewRotateYhas been removed.viewRotateZhas been removed.viewScalehas been removed.viewTranslatehas been removed.modelIdentityhas been removed.modelScalehas been removed.modelTranslatehas been removed.viewIdentityhas been removed.viewLoad2Dhas been removed.projOrthohas been removed.
BitmapText - New Features, Updates and API Changes
BitmapText.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycoordinates. The character data includes the code, position, dimensions, and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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
setMaxWidthonDynamicBitmapText, 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_SCENEis 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_SCENEis 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_SCENEis 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_SCENEis 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.addedToSceneis 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.removedFromSceneis 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 theremovedFromScenemethod now. - The
Containerwill 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.eventsis a new property that references the Scene's Event Emitter. This is now used internally.DisplayList.addChildCallbackis a new method that overrides the List callback and fires the new ADDED events.DisplayList.removeChildCallbackis a new method that overrides the List callback and fires the new REMOVED events.GameObjectCreator.eventsis a new property that references the Scene's Event Emitter. This is now used internally.GameObjectFactory.eventsis a new property that references the Scene's Event Emitter. This is now used internally.ProcessQueue.checkQueueis a new boolean property that will make sure only unique objects are added to the Process Queue.- The
Update Listnow uses the newcheckQueueproperty to ensure no duplicate objects are on the active list. DOMElementFactory,ExternFactory,ParticleManagerFactor,RopeFactoryandSpriteFactoryall no longer add the objects to the Update List, this is now handled by the ADDED events instead.Sprite,Rope,ParticleEmitterManager,ExternandDOMElementnow all override theaddedToSceneandremovedFromScenecallbacks 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.
SpineContaineris a new Game Object available viathis.add.spineContainerto 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.runtimeswhich will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo intoplugins/spine/in order for this to work and then runnpm 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-zeroerror 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.setAnimationmethod will now use thetrackIndexparameter ifignoreIfPlayingis set and run the check against this track index. Fix #4842 (thanks @vinerz) - The
SpineFilewill 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
destroymethod 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.gameDestroyis a new method that is called if the Game instance emits adestroyevent. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.SpineFilewill 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)SpineFilenow 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.willRenderis no longer hard-coded to returntrue. 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
Animationclass no longer extendsEventEmitter, 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_KEYevents have been removed. Instead, please use the new events which all carry theframeKeyparameter, which can be used to handle frame specific events. The only exception to this isANIMATION_COMPLETE_KEY, which is a key specific version of the completion event. ANIMATION_UPDATE_EVENTis a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.ANIMATION_STOP_EVENTis a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of thestopmethods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)- The Game Object
Component.Animationcomponent has been renamed toAnimationStateand has moved namespace. It's now inPhaser.Animationsinstead ofGameObjects.Componentsto help differentiate it from theAnimationclass when browsing the documentation. - The
play,playReverse,playAfterDelay,playAfterRepeatandchainSprite and Animation Component methods can now all take aPhaser.Types.Animations.PlayAnimationConfigconfiguration object, as well as a string, as thekeyparameter. 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.createis 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.generateFrameNumbersis 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.generateFrameNamesis 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,playAfterDelayandplayAfterRepeatwill 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.skipMissedFramesis 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.addMixis 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.getMixis a new method that will return the mix duration between the two given animations.AnimationManager.removeMixis a new method that will remove the mixture between either two animations, or all mixtures for the given animation.AnimationState.removeis a new method that will remove a locally stored Animation instance from a Sprite.AnimationState.getis a new method that will return a locally stored Animation instance from the Sprite.AnimationState.existsis a new method that will check if a locally stored Animation exists on the Sprite.- The internal
AnimationState.removemethod has been renamed toglobalRemove. AnimationState.textureManageris a new property that references the global Texture Manager.AnimationState.animsis a new property that contains locally created Animations in a Custom Map.AnimationState.playandSprite.playno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.AnimationState.playReverseandSprite.playReverseno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.- The
AnimationState.delayedPlaymethod has been renamed toplayAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration. - The
AnimationState.stopOnRepeatmethod has been renamed tostopAfterRepeat - The
AnimationState.getCurrentKeymethod has been renamed togetName. AnimationState.getFrameNameis a new method that will return the key of the current Animation Frame, if an animation has been loaded.AnimationState.playAfterDelayandSprite.playAfterDelayare new methods that will play the given animation after the delay in ms expires.AnimationState.playAfterRepeatandSprite.playAfterRepeatare 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.chainmethod is now available on the Sprite class. - The
AnimationState.stopAfterDelaymethod is now available on the Sprite class. - The
AnimationState.stopAfterRepeatmethod is now available on the Sprite class. - The
AnimationState.stopOnFramemethod is now available on the Sprite class. AnimationManager.createFromAsepriteis 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.AnimationStatenow 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 optionalPlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.- The
PlayAnimationConfig.frameRateproperty lets you optionally override the animation frame rate. - The
PlayAnimationConfig.durationproperty lets you optionally override the animation duration. - The
PlayAnimationConfig.delayproperty lets you optionally override the animation delay. - The
PlayAnimationConfig.repeatproperty lets you optionally override the animation repeat counter. - The
PlayAnimationConfig.repeatDelayproperty lets you optionally override the animation repeat delay value. - The
PlayAnimationConfig.yoyoproperty lets you optionally override the animation yoyo boolean. - The
PlayAnimationConfig.showOnStartproperty lets you optionally override the animation show on start value. - The
PlayAnimationConfig.hideOnCompleteproperty lets you optionally override the animation hide on complete value. - The
PlayAnimationConfig.startFrameproperty lets you optionally set the animation frame to start on. - The
PlayAnimationConfig.timeScaleproperty lets you optionally set the animation time scale factor. AnimationState.delayCounteris a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animationSTARTevents fire. Fix #4426 (thanks @bdaenen)AnimationState.hasStartedis 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.showOnStartis a new boolean property that controls if the Game Object should havesetVisible(true)called on it when the animation starts.AnimationState.hideOnCompleteis a new boolean property that controls if the Game Object should havesetVisible(false)called on it when the animation completes.- The
AnimationState.chainmethod docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does! - The
AnimationState.setDelaymethod has been removed. It never actually worked and you can now perform the same thing by calling eitherplayAfterDelayor setting thedelayproperty in the play config. - The
AnimationState.getDelaymethod has been removed. You can now read thedelayproperty directly. - The
AnimationState.setRepeatmethod has been removed. You can achieve the same thing by setting therepeatproperty in the play config, or adjusting the publicrepeatCounterproperty if the animation has started. AnimationState.handleStartis a new internal private method that handles the animation start process.AnimationState.handleRepeatis a new internal private method that handles the animation repeat process.AnimationState.handleStopis a new internal private method that handles the animation stop process.AnimationState.handleCompleteis a new internal private method that handles the animation complete process.AnimationState.emitEventsis a new internal private method that emits animation events, cutting down on duplicate code.- The
AnimationState.restartmethod has a new optional boolean parameterresetRepeatswhich controls if you want to reset the repeat counter during the restart, or not. Animation.getTotalFramesis a new method that will return the total number of frames in the animation. You can access it viathis.anims.currentAnim.getTotalFramesfrom a Sprite.Animation.calculateDurationis a new method that calculates the duration, frameRate and msPerFrame for a given animation target.- The
BuildGameObjectAnimationfunction now uses thePlayAnimationConfigobject to set the values. Sprite.playReverseis a new method that allows you to play the given animation in reverse on the Sprite.Sprite.playAfterDelayis a new method that allows you to play the given animation on the Sprite after a delay.Sprite.stopis a new method that allows you to stop the current animation on the Sprite.AnimationManager.loadhas been removed as it's no longer required.AnimationManager.staggerPlayhas been fixed so you can now pass in negative stagger values.AnimationManager.staggerPlayhas a new optional boolean parameterstaggerFirst, which allows you to either include or exclude the first child in the stagger calculations.- The
Animation.completeAnimationmethod has been removed as it's no longer required. - The
Animation.loadmethod has been removed as it's no longer required. - The
Animation.setFramemethod has been removed as it's no longer required. - The
Animation.getFirstTickmethod has no longer needs theincludeDelayparameter, as it's handled byAnimationStatenow. - The
Animation.getFramesmethod has a new optional boolean parametersortFrameswhich will run a numeric sort on the frame names after constructing them, if a string-based frame is given. Types.Animations.Animationhas a new boolean propertysortFrames, which lets Phaser numerically sort the generated frames.AnimationState.timeScaleis a new public property that replaces the old private_timeScaleproperty.AnimationState.delayis a new public property that replaces the old private_delayproperty.AnimationState.repeatis a new public property that replaces the old private_repeatproperty.AnimationState.repeatDelayis a new public property that replaces the old private_repeatDelayproperty.AnimationState.yoyois a new public property that replaces the old private_yoyoproperty.AnimationState.inReverseis a new public property that replaces the old private_reverseproperty.AnimationState.startAnimationis a new public method that replaces the old private_startAnimationmethod.- The
AnimationState.getProgressmethod has been fixed so it will return correctly if the animation is playing in reverse. - The
AnimationState.globalRemovemethod will now always be called when an animation is removed from the global Animation Manager, not just once. - The
AnimationState.getRepeatmethod has now been removed. You can get the value from therepeatproperty. - The
AnimationState.setRepeatDelaymethod has now been removed. You can set the value using therepeatDelayconfig property, or changing it at run-time. AnimationState.completeis a new method that handles the completion in animation playback.- The
AnimationState.setTimeScalemethod has now been removed. You can set the value using thetimeScaleconfig property, or changing it at run-time. - The
AnimationState.getTimeScalemethod has now been removed. You can read the value using thetimeScaleproperty. - The
AnimationState.getTotalFramesmethod has been fixed and won't error if called when no animation is loaded. - The
AnimationState.setYoyomethod has now been removed. You can set the value using theyoyoconfig property, or changing it at run-time. - The
AnimationState.getYoyomethod has now been removed. You can read the value using theyoyoproperty. - The
AnimationState.stopAfterRepeatmethod now has an optional parameterrepeatCount, 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.updateFramemethod has now been removed. Everything is handled bysetCurrentFrameinstead, which removes one extra step out of the update process. GenerateFrameNameswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswould 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.GenerateFrameNumberscan now accept thestartandendparameters in reverse order, meaning you can now do{ start: 10, end: 1 }to create the animation in reverse.GenerateFrameNamescan now accept thestartandendparameters 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.createDynamicLayermethod has been renamed tocreateLayer. - The
Tilemap.createStaticLayermethod has been removed. UsecreateLayerinstead. - The
Tilemap.createBlankDynamicLayermethod has been renamed tocreateBlankLayer. - The
Tilemap.convertLayerToStaticmethod has been removed as it is no longer required. - The
TilemapLayerWebGLRendererfunction 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.TilemapOrientationTypeis a new type def that holds the 4 types of map orientation now supported.- The
Tile.updatePixelXYmethod now updates the tile XY position based on map type. ParseTilesetswill now correctly handle non-consecutive tile IDs. It also now correctly sets themaxIdproperty, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)Tilemap.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.LayerData.orientationis a new property that holds the tilemap layers orientation constant.LayerData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.MapData.orientationis a new property that holds the tilemap layers orientation constant.MapData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.Tilemaps.Components.HexagonalWorldToTileYis a new function that converts a world Y coordinate to hexagonal tile Y coordinate.Tilemaps.Components.StaggeredWorldToTileYis a new function that converts a world Y coordinate to staggered tile Y coordinate.Tilemaps.Components.HexagonalWorldToTileXYis a new function that converts world coordinates to hexagonal tile coordinates.Tilemaps.Components.IsometricWorldToTileXYis a new function that converts world coordinates to isometric tile coordinates.Tilemaps.Components.StaggeredWorldToTileXYis a new function that converts world coordinates to staggered tile coordinates.Tilemaps.Components.HexagonalTileToWorldYis a new function that converts a hexagonal Y coordinate to a world coordinate.Tilemaps.Components.StaggeredTileToWorldYis a new function that converts a staggered Y coordinate to a world coordinate.Tilemaps.Components.HexagonalTileToWorldXYis a new function that converts hexagonal tile coordinates to world coordinates.Tilemaps.Components.IsometricTileToWorldXYis a new function that converts isometric tile coordinates to world coordinates.Tilemaps.Components.StaggeredTileToWorldXYis a new function that converts staggered tile coordinates to world coordinates.Tilemaps.Components.GetTileToWorldXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldXXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetCullTilesFunctionis a new function that returns the correct culling function to use.Tilemaps.Components.HexagonalCullTilesis a new function that culls tiles in a hexagonal map.Tilemaps.Components.StaggeredCullTilesis a new function that culls tiles in a staggered map.Tilemaps.Components.IsometricCullTilesis a new function that culls tiles in a isometric map.Tilemaps.Components.CullBoundsis a new function that calculates the cull bounds for an orthogonal map.Tilemaps.Components.HexagonalCullBoundsis a new function that calculates the cull bounds for a hexagonal map.Tilemaps.Components.StaggeredCullBoundsis a new function that calculates the cull bounds for a staggered map.Tilemaps.Components.RunCullis a new function that runs the culling process from the combined bounds and tilemap.Tilemap._convertis a new internal private hash of tilemap conversion functions used by the public API.- The
Tilemap._isStaticCallmethod 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
GetTilesWithinWorldXYcomponent directly, saving lots of overhead. - The method
Tilemap.weightedRandomizehas changed so that the parameterweightedIndexesis now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional. - The method
TilemapLayer.weightedRandomizehas changed so that the parameterweightedIndexesis 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.Meshis 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.Vertexis a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.Geom.Mesh.Faceis a new class that consists of references to the threeVertexinstances that construct a single Face in a Mesh and provides methods for manipulating them.Geom.Mesh.GenerateVertsis a new function that will return an array ofVertexandFaceobjects 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.GenerateGridVertsis a new function that will generate a series ofVertexobjects in a grid format, based on the givenGenerateGridConfigconfig 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.GenerateObjVertsis a new function that will generate a series ofVertexobjects 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.ParseObjis a new function that will parse a triangulated Wavefront OBJ file into model data into a format that theGenerateObjVertsfunction can consume.Geom.Mesh.ParseObjMaterialis 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.RotateFaceis a new function that will rotate a Face by a given amount, based on an optional center of rotation.Loader.OBJFileis 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
MeshFactorysignatures have changed toscene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first.indiciesis a new parameter that allows you to provide indexed vertex data to create the Mesh from, where theindiciesarray holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. Theindiciesarray is optional. If your data is not indexed, then simply passnullor an empty array for this parameter. - The
MeshGame 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.addVerticesis 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.addVerticesFromObjis a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the newOBJFilewith athis.load.objcall, 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.hideCCWis 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.modelPositionis a new Vector3 property that allows you to translate the position of all vertices in the Mesh.Mesh.modelRotationis a new Vector3 property that allows you to rotate all vertices in the Mesh.Mesh.modelScaleis a new Vector3 property that allows you to scale all vertices in the Mesh.Mesh.panXis a new function that will translate the view position of the Mesh on the x axis.Mesh.panYis a new function that will translate the view position of the Mesh on the y axis.Mesh.panZis a new function that will translate the view position of the Mesh on the z axis.Mesh.setPerspectiveis a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.Mesh.setOrthois a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.Mesh.clearis a new method that will destroy all Faces and Vertices and clear the Mesh.Mesh.depthSortis a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.Mesh.addVertexis a new method that allows you to add a new single Vertex into the Mesh.Mesh.addFaceis a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.Mesh.getFaceCountnew is a new method that will return the total number of Faces in the Mesh.Mesh.getVertexCountnew is a new method that will return the total number of Vertices in the Mesh.Mesh.getFacenew is a new method that will return a Face instance from the Mesh based on the given index.Mesh.getFaceAtnew 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.verticesis now an array ofGameObject.Vertexinstances, not a Float32Array.Mesh.facesis a new array ofGameObject.Faceinstances, which is populated during a call to methods likeaddVerticesoraddModel.Mesh.totalRenderedis a new property that holds the total number of Faces that were rendered in the previous frame.Mesh.setDebugis 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
BringToTopto 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
MeshGame Object now extends theSingleAlphacomponent 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 standardsetAlphamethods. 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
colorsparameter in the constructor, factory method andaddVerticesmethod. 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
alphasparameter in the constructor, factory method andaddVerticesmethod. If a number, instead of an array, it will be used as the alpha for all vertices created. Mesh.debugGraphicis a new property that holds the debug Graphics instance reference.Mesh.debugCallbackis a new property that holds the debug render callback.Mesh.renderDebugVertsis a new method that acts as the default render callback forsetDebugif none is provided.Mesh.preDestroyis a new method that will clean-up the Mesh arrays and debug references on destruction.Mesh.isDirtyis a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically inpreUpdateto avoid generating lots of math when nothing has changed.- The
Mesh.uvarray has been removed. All UV data is now bound in the Vertex instances. - The
Mesh.colorsarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.alphasarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.tintFillproperty is now abooleanand defaults tofalse.
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.refreshis now called when theGame.READYevent 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
inputMouseCapturehas been removed, as this is now split into 3 new config options: inputMousePreventDefaultDownis a new config option that allows you to controlpreventDefaultcalls specifically on mouse down events. Set it viainput.mouse.preventDefaultDownin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultUpis a new config option that allows you to controlpreventDefaultcalls specifically on mouse up events. Set it viainput.mouse.preventDefaultUpin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultMoveis a new config option that allows you to controlpreventDefaultcalls specifically on mouse move events. Set it viainput.mouse.preventDefaultMovein the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultWheelis a new config option that allows you to controlpreventDefaultcalls specifically on mouse wheel events. Set it viainput.mouse.preventDefaultWheelin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.- The
MouseManager.captureproperty has been removed, as this is now split into 3 new config options (see below) MouseManager.preventDefaultDownis a new boolean property, set via theinputMousePreventDefaultDownconfig option that allows you to toggle capture of mouse down events at runtime.MouseManager.preventDefaultUpis a new boolean property, set via theinputMousePreventDefaultUpconfig option that allows you to toggle capture of mouse up events at runtime.MouseManager.preventDefaultMoveis a new boolean property, set via theinputMousePreventDefaultMoveconfig option that allows you to toggle capture of mouse move events at runtime.MouseManager.preventDefaultWheelis a new boolean property, set via theinputMousePreventDefaultWheelconfig option that allows you to toggle capture of mouse wheel at runtime.- In the
MouseManagerthe 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
GamepadPluginwill now callrefreshPadsas 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 viathis.input.gamepad.pad1and 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._createdis 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.downwill 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
useHandCursorenabled, 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.shutdownmethod 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.processOverEventshas 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.tintTopLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTLwhich has now been removed.Tint.tintTopRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTRwhich has now been removed.Tint.tintBottomLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBLwhich has now been removed.Tint.tintBottomRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBRwhich has now been removed.- The property
Tint._isTintedhas been removed as it's no longer required. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they now read the color value asoutTint.bgrinstead ofoutTint.rgb. This allows the colors to remain in RGB order within the Tint component. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they no longer have a 3-way check on theoutTintEffectvalue. - The
Multi Pipeline,Bitmap Text,Render Texture,Text,TileSpriteandCameranow all read the tint values from the public properties instead of the private_tintTLetc ones. They also now set thetintEffectvalue directly from thetintFillproperty, removing another conditional check. - The function
GetColorFromValuehas been removed as it's no longer used internally. - The
Rope.tintFillproperty is now a boolean, not an integer, and can no longer take2as 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
getTintAppendFloatAlphaAndSwaphave been replaced withgetTintAppendFloatAlphainstead. - As a result of the change to the shader, the Multi Pipeline now uses the
WebGLRenderer.whiteTextureandtintEffectmode 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.whiteTextureis 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
TextureManagernow generates a new texture with the key__WHITEdurings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines. Config.images.whiteis 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
Bodyclass has a new boolean propertypushable(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.setPushableis a new chainable method that allows you to set thepushablestate of a Body.Arcade.Components.Pushableis 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.disableUpdateis a new method that will prevent the Arcade Physics Worldupdatemethod 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.enableUpdateis 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.customUpdateis a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. Iftruethe World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)Physics.Arcade.Body.setCollideWorldBoundsnow has a new optional parameteronWorldBoundswhich allows you to enable the Body'sonWorldBoundsproperty in the same call (thanks @samme)ArcadePhysics.Body.setMaxVelocityXis a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)ArcadePhysics.Body.setMaxVelocityYis a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)- The
PhysicsGroupconfig now has two new optional propertiesmaxVelocityXandmaxVelocityYwhich allows you to set the maximum velocity on bodies added to the Group (thanks @samme) - The
Arcade.Body.resetFlagsmethod has a new optional boolean parameterclear. If set, it clears thewasTouchingflags on the Body. This happens automatically whenBody.resetis called. Previous to this, the flags were not reset until the next physics step (thanks @samme) Physics.Arcade.ProcessXis a new set of functions, called by theSeparateXfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Physics.Arcade.ProcessYis a new set of functions, called by theSeparateYfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Arcade.Body.centervalues 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_STEPevent now has a new parameter: the delta argument (thanks @samme) - The Arcade Body
dragproperty 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 usedragyou will need to change any existing drag values to get the same effects as before. Convertdragtodrag ^ 60ordrag ^ fpsif 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.
AtlasJSONFileno longer stores the JSON in the JSON Cache once the texture has been created.AtlasXMLFileno longer stores the XML in the XML Cache once the texture has been created.UnityAtlasFileno longer stores the Text in the Text Cache once the texture has been created.BitmapFontFileno longer stores the XML in the XML Cache once the texture has been created.- You can now use
TextureManager.removeto 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.ColorMatrixis 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.setmethod allows you to set the values of a ColorMatrix. - The
ColorMatrix.resetmethod will reset the ColorMatrix to its default values. - The
ColorMatrix.getDatamethod will return the data in the ColorMatrix as a Float32Array, useful for setting in a shader uniform. - The
ColorMatrix.brightnessmethod lets you set the brightness of the ColorMatrix. - The
ColorMatrix.saturatemethod lets you set the saturation of the ColorMatrix. - The
ColorMatrix.desaturatemethod lets you desaturate the colors in the ColorMatrix. - The
ColorMatrix.huemethod lets you rotate the hues of the ColorMatrix by the given amount. - The
ColorMatrix.grayscalemethod converts the ColorMatrix to grayscale. - The
ColorMatrix.blackWhitemethod converts the ColorMatrix to black and whites. - The
ColorMatrix.contrastmethod lets you set the contrast of the ColorMatrix. - The
ColorMatrix.negativemethod converts the ColorMatrix to negative values. - The
ColorMatrix.desaturateLuminancemethod applies a desaturated luminance to the ColorMatrix. - The
ColorMatrix.sepiamethod applies a sepia tone to the ColorMatrix. - The
ColorMatrix.nightmethod applies a night time effect to the ColorMatrix. - The
ColorMatrix.lsdmethod applies a trippy color effect to the ColorMatrix. - The
ColorMatrix.brownmethod applies a brown tone to the ColorMatrix. - The
ColorMatrix.vintagePinholemethod applies a vintage pinhole color effect to the ColorMatrix. - The
ColorMatrix.kodachromemethod applies a kodachrome color effect to the ColorMatrix. - The
ColorMatrix.technicolormethod applies a technicolor color effect to the ColorMatrix. - The
ColorMatrix.polaroidmethod applies a polaroid color effect to the ColorMatrix. - The
ColorMatrix.shiftToBGRmethod shifts the values of the ColorMatrix into BGR order. - The
ColorMatrix.multiplymethod 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#RESIZEevent no longer sends theresolutionas a parameter. - The
BaseCamera.resolutionproperty has been removed. - The internal private
BaseCamera._cx,_cy,_cwand_chproperties has been removed, usex,y,widthandheightinstead. - The
BaseCamera.preRendermethod no longer receives or uses theresolutionparameter. - The
Camera.preRendermethod no longer receives or uses theresolutionparameter. - The
CameraManager.onResizemethod no longer receives or uses theresolutionparameter. - The
Core.Config.resolutionproperty has been removed. - The
TextStyle.resolutionproperty 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
CanvasRendererno longer reads or uses the Game Config resolution property. - The
PipelineManager.resizemethod along withWebGLPipeline.resizeand anything else that extends them no longer receives or uses theresolutionparameter. - The
WebGLRenderer.resizeandonResizemethods no longer receives or uses theresolutionparameter. - The
ScaleManager.resolutionproperty 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.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Intersects.GetLineToPointsis 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.GetRaysFromPointToPolygonis 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.Translateis a new function that allows you to translate all the points of a polygon by the given values.Geom.Polygon.Simplifyis 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.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.getTweensOfhas a new parameterincludePending. 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.hasBootedis 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 theWebGLRenderer.addPipelinemethod, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)- The WebGL Renderer will now add the pipelines during the
bootmethod, instead ofinit. - You can now use
this.rendererfrom within a Scene, as it's now a Scene-level property and part of the Injection Map. Clock.addEventcan now take an existingTimerEventobject, as well as a config object. If aTimerEventis 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.removeEventis a new method that allows you to remove aTimerEvent, or an array of them, from all internal lists of the current Clock.Group.getMatchingis a new method that will return any members of the Group that match the given criteria, such asgetMatching('visible', true)(thanks @atursams)Utils.Array.SortByDigitsis 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 callingGroup.createMultipleorGroup.createFromConfig, can now accept the following new properties:setOrigin: { x, y, stepX, stepY }which are applied to the items created by the Group.Transform.copyPositionis a new method that will copy the position from the given object to the Game Object (thanks @samme)- The
Text.MeasureTextfunction, 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 newactualBoundingBoxAscentfunctions 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.GetCalcMatrixis 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,StarandTriangle. This dramatically reduces the amount of duplicate code across the API.Utils.Array.Matrix.Translateis a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.Vertor3.addScaleis 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
easeParamsin the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh) BitmapMask.createMaskis 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.clearMaskwill 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.Quaternionnow has a new propertyonChangeCallbackwhich, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.- The
Quaternion.setmethod has a new optional boolean parameterupdate(defaults totrue), which will call theonChangeCallbackif set. Quaternion.setFromEuleris a new method that will set the quaternion from the givenEulerobject, optionally calling theonChangeCallbackin the process.Quaternion.setFromRotationMatrixis a new method that will set the rotation of the quaternion from the given Matrix4.Vector3.setFromMatrixPositionis a new method that will set the components of the Vector3 based on the position of the given Matrix4.Vector3.setFromMatrixColumnis a new method that will set the components of the Vector3 based on the specified Matrix4 column.Vector3.fromArrayis a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.Vector3.minis a new method that will set the components of the Vector3 based on theMain.minbetween it and the given Vector3.Vector3.maxis a new method that will set the components of the Vector3 based on theMain.maxbetween it and the given Vector3.Vector3.addVectorsis a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.Vector3.addScalaris a new method that will multiply the components of the Vector3 by the scale value given.Vector3.applyMatrix3is a new method that will take a Matrix3 and apply it to the Vector3.Vector3.applyMatrix4is a new method that will take a Matrix4 and apply it to the Vector3.Vector3.projectViewMatrixis a new method that multiplies the Vector3 by the given view and projection matrices.Vector3.unprojectViewMatrixis a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.Matrix4.setValuesis a new method that allows you to set all of the matrix components individually. Most internal methods now use this.Matrix.multiplyToMat4is a new method that multiplies a Matrix4 by the givensrcMatrix4 and stores the results in theoutMatrix4.Matrix4.fromRotationXYTranslationis a new method that takes the rotation and position vectors and builds this Matrix4 from them.Matrix4.getMaxScaleOnAxisis a new method that will return the maximum axis scale from the Matrix4.Matrix4.lookAtRHis a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.Matrix4.transformis a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.Matrix4.multiplyMatricesis a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.Matrix4.premultiplyis a new method that takes a Matrix4 and multiplies it by the current Matrix4.Matrix4.getInverseis a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.CameraManager.getVisibleChildrenis a new method that is called internally by theCameraManager.rendermethod. It filters the DisplayList, so that Game Objects that pass thewillRendertest 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.setDampingis a new method that allows you to set theuseDampingproperty of a Body in a chainable way. Fix #5352 (thanks @juanitogan)- The
GameObjects.Graphics.fillGradientStylemethod 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.PipelineConfigis a new configuration object that you can set in the Game Config under thepipelineproperty. 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 thepipelineobject, or set it under therendersub-config.Utils.Object.DeepCopyis a new function that will recursively deep copy an array of object.Time.TimerEvent.getRemainingis a new method that returns the time interval until the next iteration of the Timer Event (thanks @samme)Time.TimerEvent.getRemainingSecondsis a new method that returns the time interval until the next iteration of the Timer Event in seconds (thanks @samme)Time.TimerEvent.getOverallRemainingis a new method that returns the time interval until the last iteration of the Timer Event (thanks @samme)Time.TimerEvent.getOverallRemainingSecondsis a new method that returns the time interval until the last iteration of the Timer Event in seconds (thanks @samme)GameObjects.Video.loadMediaStreamis 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.ColorSpectrumis 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.AsepriteFileis 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 viathis.load.asesprite(png, json).GameObject.displayListis 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.Earcutand is fully documented. Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself. - The constant
Phaser.Renderer.WebGL.BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.FLOATvalue has been removed as it wasn't used internally. Pointer.downTimenow 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.upTimenow 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.getDurationmethod now uses the new PointerdownTimeandupTimevalues, 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
BaseShaderdefault vertex shader now includes theoutTexCoordvec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok) - When using the
GameObjectCreatorforContainersyou can now specify thechildrenproperty in the configuration object. Textures.Parsers.JSONHashwill now perform ahasOwnPropertycheck when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes fromJSON.parse. Fix #4768 (thanks @RollinSafary)- The
Camera3DPlugin 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.seekwill 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
inputWindowEventsis set in the Game Config, then theMouseManagerwill now listen for the events onwindow.topinstead of justwindow, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in atry/catchblock, as not all sites allow access towindow.top(specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow) MouseManager.isTopis a new boolean read-only property that flags if the mouse event listeners were attached towindow.top(true), or justwindow(false). By default Phaser will attemptwindow.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back towindowin those cases and set this property to false (thanks BunBunBun)Types.GameObjects.Text.GetTextSizeObjectis a new type def for the GetTextSize function results.Utils.Array.StableSorthas 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. Theinplacefunction has been removed, just callStableSort(array)directly now. All classes that usedStableSort.inplacehave 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.setOriginwill now callupdateDisplayOriginon the items array, otherwise the effects can't be seen when rendering.- You can now set the
ArcadeWorld.fixedStepproperty via theArcadeWorldConfigobject (thanks @samme) Utils.Array.NumerArraycan now accept thestartandendparameters in reverse order, i.e.10, 1will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.DataManager.Events.DESTROYis a new event that the Data Manager will listen for from its parent and then call its owndestroymethod when received.- The
Quaternionclass constructor will now default the values to0,0,0,1if they're not provided, making it an identity quaternion, rather than the0,0,0,0it was before. - You can now set the
ParticleEmitter.reservevalue via the emitter configuration object (thanks @vforsh) - Setting the
pixelArtconfig option will now setantialiasGLtofalse, as well asantialias. Fix #5309 (thanks @Vegita2) - The
Shapeclass now includes theComputedSizecomponent properties and methods directly in the class, rather than applying as a mixin.setSizeis now flagged as beingprivate, 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.maxParallelDownloadsvalue is now set to 6 if running on Android, or 32 on any other OS. This avoidsnet::ERR_FAILEDissues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary) - When running an Arcade Physics
overlaptest against aStaticBody, it will no longer set theblockedstates 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
LineGame 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
Quaternionclass now has 4 new private properties:_x,_y,_zand_wand 4 new getters and setters for the public versions. It also now passes most methods viasetto allow for the onChange callback to be invoked. This does not change the public-facing API. Groupnow extendsEventEmitter, allowing you to emit custom events from within a Group.Device.Audio.wavnow usesaudio/wavas thecanPlayTypecheck string, instead ofaudio/wav; codecs="1", which should allow iOS13 to play wav files again.- In the
Loader.FileTypes.TextFileconfig you can now override the type and cache destination for the file. Loader.MultiFilewill 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.tintvalue is now0xffffff(previously, it was0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh) SceneManager.startwill now reset theSceneSystems.sceneUpdatereference toNOOP. This gets set back to the Scene update method again duringbootScene(if it has one) and stops errors with external plugins and multi-part files that may triggerupdatebeforecreatehas been called. Fix #4629 (thanks @Osmose)Phaser.Scene.rendereris a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.- The
CanvasRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead. - Since iOS 13, iPads now identify as MacOS devices. A new maxTouchPoint check is now part of the
Device.OStests, stopping iPads from being flagged as desktop devices. Fix #5389 (thanks @SBCGames) - The
BitmapMask.prevFramebufferproperty has been removed as it's no longer required, due to the fbo stack in the renderer. - The
TextureManager.addGLTexturemethod has been updated so that thewidthandheightparameters are now optional. If not provided, and if available, they will be read from the given WebGLTexture instead (thanks @hexus) GameObjects.Components.Depth.depthListis 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
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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
ProcessQueuewas emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar) - The
GridAlignaction didn't work if only theheightparameter was set. Fix #5019 (thanks @halilcakar) - The
Color.HSVToRGBfunction has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX) - Previously, the
easeParamsarray within a Tweenspropsobject, 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.setRenderToTextureitszoomandrotationvalues would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok) GameObjects.Shape.Gridwould render a white fill even if you passedundefinedas the fill color in the constructor. It now doesn't render cells if no fill color is given.- The
onMouseevents in the Input Manager didn't reset theactivePointerproperty 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
GetScreenOrientationfunction will now check forwindow.orientationfirst, 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 emitorientationchangeevents correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu) Time.Clock.addEventcan now take an instance of aTimerEventas its parameter. Fix #5294 (thanks @samme @EmilSV)GameConfig.audionow defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)- The
Loader.pathwas 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.getMatchingwould always return an empty array. It now returns matching children (thanks @samme)- The
ParticleManagerWebGLRenderernow 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
ParticleManagerCanvasRenderernow calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also usessetToContextinternally. 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
GraphicsWebGL Renderer will now default topathOpen = true. This fixes issues under WebGL where, for example, adding an arc and callingstrokePath, without first callingbeginPathwill no longer cause rendering artefacts when WebGL tries to close the path with a single tri. Graphics.strokeRoundedRectnow issuesmoveTocommands 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
snapshotin WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in theWebGLSnapshotfunction. Fix #4956 (thanks @gammafp @telinc1) Particles.EmitterOp.setMethodswill now reset bothonEmitandonUpdateto 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.EmitterOpnow cleanly separates between the different types of property configuration options.start | endwill now ease between the two values,min | maxwill pick a random value between them andrandom: []will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)- When setting both
transparent: trueandbackgroundColorin 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
EllipseGame Object now will update the width, height, and geometric position in thesetSizemethod (thanks @PhaserEditor2D) - When measuring the last word in a line in a
TextGame Object, it no longer adds extra white space to the end (thanks @rexrainbow) Utils.Array.Removewould 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.TriangleToLinewouldn't returntrueif 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)
BitmapMaskwould 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.MoveTofunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.DOM.GetInnerHeightfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Bobclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsManagerclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsPluginclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Particles.EmitterOpclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.GetTextSizefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.MeasureTextfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.TextStylefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Input.CreatePixelPerfectHandlerfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapCircfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapRectfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Tilemapnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Componentsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.MatterGameObjectclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.PointerConstraintclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetPhysicsPluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetScenePluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Structs.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Tilemaps.Parsers.Tiledfunction has now been exposed on the Phaser namespace (thanks @samme) - Every single
Tilemap.Componentfunction 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:
TextureTintPipelineis now called theMultiPipeline.TextureTintStripPipelineis now called theRopePipeline.ForwardDiffuseLightPipelineis now called theLightPipeline.
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.fragis now calledLight.frag.TextureTint.fragis now calledMulti.frag.TextureTint.vertis now calledMulti.vert.
Other pipeline changes are as follows:
- None of the shaders or pipelines use the
uViewMatrixanduModelMatrixuniforms 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.WebGLPipelineConfigis a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.Types.Renderer.WebGL.WebGLPipelineAttributesConfigis 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
rendererproperty automatically, so it's no longer required in the config. - All pipelines will now work out the
glproperty automatically, so it's no longer required in the config. - All pipelines will now extract the
nameproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexCapacityproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexSizeproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexDataproperty from the config, allowing you to set it externally. - All pipelines will now extract the
attributesproperty from the config, allowing you to set it externally. - All pipelines will now extract the
topologyproperty from the config, allowing you to set it externally. - The
WebGLPipeline.shouldFlushmethod now accepts an optional parameteramount. If given, it will returntrueif 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
RopePipelinenow extendsMultiPipelineand just changes the topolgy, vastly reducing the filesize. - The
WebGLPipeline.flushLockedproperty 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.setPipelinemethod, 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.set1fwill set a 1f uniform based on the given name.WebGLPipeline.set2fwill set a 2f uniform based on the given name.WebGLPipeline.set3fwill set a 3f uniform based on the given name.WebGLPipeline.set4fwill set a 4f uniform based on the given name.WebGLPipeline.set1fvwill set a 1fv uniform based on the given name.WebGLPipeline.set2fvwill set a 2fv uniform based on the given name.WebGLPipeline.set3fvwill set a 3fv uniform based on the given name.WebGLPipeline.set4fvwill set a 4fv uniform based on the given name.WebGLPipeline.set1ivwill set a 1iv uniform based on the given name.WebGLPipeline.set2ivwill set a 2iv uniform based on the given name.WebGLPipeline.set3ivwill set a 3iv uniform based on the given name.WebGLPipeline.set4ivwill set a 4iv uniform based on the given name.WebGLPipeline.set1iwill set a 1i uniform based on the given name.WebGLPipeline.set2iwill set a 2i uniform based on the given name.WebGLPipeline.set3iwill set a 3i uniform based on the given name.WebGLPipeline.set4iwill set a 4i uniform based on the given name.WebGLPipeline.setMatrix2fvwill set a matrix 2fv uniform based on the given name.WebGLPipeline.setMatrix3fvwill set a matrix 3fv uniform based on the given name.WebGLPipeline.setMatrix4fvwill 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.setFloat1has been removed. Please useset1finstead.WebGLPipeline.setFloat2has been removed. Please useset2finstead.WebGLPipeline.setFloat3has been removed. Please useset3finstead.WebGLPipeline.setFloat4has been removed. Please useset4finstead.WebGLPipeline.setFloat1vhas been removed. Please useset1fvinstead.WebGLPipeline.setFloat2vhas been removed. Please useset2fvinstead.WebGLPipeline.setFloat3vhas been removed. Please useset3fvinstead.WebGLPipeline.setFloat4vhas been removed. Please useset4fvinstead.WebGLPipeline.setInt1has been removed. Please useset1iinstead.WebGLPipeline.setInt2has been removed. Please useset2iinstead.WebGLPipeline.setInt3has been removed. Please useset3iinstead.WebGLPipeline.setInt4has been removed. Please useset4iinstead.WebGLPipeline.setMatrix1has been removed. Please usesetMatrix2fvinstead.WebGLPipeline.setMatrix2has been removed. Please usesetMatrix3fvinstead.WebGLPipeline.setMatrix3has been removed. Please usesetMatrix4fvinstead.
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.pipelinesis no longer a plain object containing pipeline instances. It's now an instance of thePipelineManagerclass. This instance is created during the init and boot phase of the renderer.- The
WebGLRenderer.currentPipelineproperty no longer exists, instead usePipelineManager.current. - The
WebGLRenderer.previousPipelineproperty no longer exists, instead usePipelineManager.previous. - The
WebGLRenderer.hasPipelinemethod no longer exists, instead usePipelineManager.has. - The
WebGLRenderer.getPipelinemethod no longer exists, instead usePipelineManager.get. - The
WebGLRenderer.removePipelinemethod no longer exists, instead usePipelineManager.remove. - The
WebGLRenderer.addPipelinemethod no longer exists, instead usePipelineManager.add. - The
WebGLRenderer.setPipelinemethod no longer exists, instead usePipelineManager.set. - The
WebGLRenderer.rebindPipelinemethod no longer exists, instead usePipelineManager.rebind. - The
WebGLRenderer.clearPipelinemethod no longer exists, instead usePipelineManager.clear.
The Pipeline Manager also offers the following new features:
- The
PipelineManager.resizemethod automatically handles resize events across all pipelines. - The
PipelineManager.preRendermethod calls the pre-render method of all pipelines. - The
PipelineManager.rendermethod calls the render method of all pipelines. - The
PipelineManager.postRendermethod calls the post-render method of all pipelines. - The
PipelineManager.setMultimethod automatically binds the Multi Texture Pipeline, Phaser's default. - The
PipelineManager.clearmethod will clear the pipeline, store it inpreviousand free the renderer. - The
PipelineManager.rebindmethod will reset the rendering context and restore thepreviouspipeline, if set.
New constants have been created to help you reference a pipeline without needing to use strings:
Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINEfor the Bitmap Mask Pipeline.Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINEfor the Light 2D Pipeline.Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINEfor the Single Pipeline.Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINEfor the Multi Pipeline.Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINEfor 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture that was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLPipeline.forceZerois a new property that informs Game Objects if the pipeline requires a zero bound texture unit.WebGLPipeline.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLRenderer.unbindTexturesis a new method that will activate and then null bind all WebGL textures.Renderer.WebGL.Utils.parseFragmentShaderMaxTexturesis 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.getComponentCountfunction has been removed as this is no longer required internally.
WebGLRenderer New Features, Updates and API Changes
WebGLRenderer.instancedArraysExtensionis a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.WebGLRenderer.vaoExtensionis a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.WebGLRenderer.resetProgramis a new method that will rebind the current program, without flushing or changing any properties.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.WebGLRenderer.finalTypeis a new boolean property that signifies if the current Game Object being rendered is the final one in the list.- The
WebGLRenderer.updateCanvasTexturemethod will now setgl.UNPACK_PREMULTIPLY_ALPHA_WEBGLto 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.previousPipelineis a new property that is set during a call toclearPipelineand used during calls torebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.- The
WebGLRenderer.rebindPipelinemethod has been changed slightly. Previously, you had to specify thepipelineInstance, but this is now optional. If you don't, it will use the newpreviousPipelineproperty instead. If not set, or none given, it will now return without throwing gl errors as well. WebGLRenderer.defaultScissoris a new property that holds the default scissor dimensions for the renderer. This is modified duringresizeand avoids continuous array generation in thepreRenderloop.- The
WebGLRenderer.nativeTexturesarray has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in theTextureSourceobjects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy. - The
WebGLRenderer.deleteTexturemethod has a new optional boolean parameterresetwhich allows you to control if theWebGLRenderer.resetTexturesmethod is called, or not, after the texture is deleted. - The
WebGLRenderer.getMaxTexturesmethod has been removed. This is no longer needed as you can use theWebGLRenderer.maxTexturesproperty instead. - The
WebGLRenderer.setProgrammethod now returns a boolean.trueif the program was set, otherwisefalse. - The
WebGLRenderer.setVertexBuffermethod now returns a boolean.trueif the buffer was set, otherwisefalse. WebGLRenderer.setFloat1has been removed. UseWebGLPipeline.set1forWebGLShader.set1finstead.WebGLRenderer.setFloat2has been removed. UseWebGLPipeline.set2forWebGLShader.set2finstead.WebGLRenderer.setFloat3has been removed. UseWebGLPipeline.set3forWebGLShader.set3finstead.WebGLRenderer.setFloat4has been removed. UseWebGLPipeline.set4forWebGLShader.set4finstead.WebGLRenderer.setFloat1vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set1fvinstead.WebGLRenderer.setFloat2vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set2fvinstead.WebGLRenderer.setFloat3vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set3fvinstead.WebGLRenderer.setFloat4vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set4fvinstead.WebGLRenderer.setInt1has been removed. UseWebGLPipeline.set1fiorWebGLShader.set1iinstead.WebGLRenderer.setInt2has been removed. UseWebGLPipeline.set1fiorWebGLShader.set2iinstead.WebGLRenderer.setInt3has been removed. UseWebGLPipeline.set1fiorWebGLShader.set3iinstead.WebGLRenderer.setInt4has been removed. UseWebGLPipeline.set1fiorWebGLShader.set4iinstead.WebGLRenderer.setMatrix2has been removed. UseWebGLPipeline.setMatrix2fvorWebGLShader.setMatrix2fvinstead.WebGLRenderer.setMatrix3has been removed. UseWebGLPipeline.setMatrix3fvorWebGLShader.setMatrix3fvinstead.WebGLRenderer.setMatrix4has been removed. UseWebGLPipeline.setMatrix4fvorWebGLShader.setMatrix4fvinstead.- The
WebGLRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead. WebGLRenderer.fboStackis a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.WebGLRenderer.pushFramebufferis 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 ofsetFramebuffer. Remember to callpopFramebufferafter using it.WebGLRenderer.popFramebufferis a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.WebGLRenderer.setFramebufferhas a new optional boolean parameterresetTextureswhich will reset the WebGL Textures, if set totrue(which is the default).WebGLRenderer.isBootedis a new boolean property that lets you know if the rendere has fully finished booting.- The
WebGLRenderernow extends the Event Emitter, allowing you to listen to renderer specific events. Phaser.Renderer.WebGL.Eventsis a new WebGL Renderer namespace for events.WebGL.Events.PRE_RENDERis a new event dispatched by the WebGL Renderer. This happens right at the start of the render process.WebGL.Events.RENDERis 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_RENDERis a new event dispatched by the WebGL Renderer. This happens right at the end of the render process.WebGL.Events.RESIZEis 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.renderToTextureproperty has been removed. Effects are now handled via pipelines. - The
Camera.renderToGameproperty has been removed. Effects are now handled via pipelines. - The
Camera.canvasproperty has been removed. Textures are handled by pipelines. - The
Camera.contextproperty has been removed. Textures are handled by pipelines. - The
Camera.glTextureproperty has been removed. GL Textures are handled by pipelines. - The
Camera.framebufferproperty has been removed. GL Framebuffers are handled by pipelines. - The
Camera.setRenderToTexturemethod has been removed. Effects are now handled via pipelines. - The
Camera.clearRenderToTexturemethod 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.zoomXis a new property that allows you to specifically set the horizontal zoom factor of a Camera.Camera.zoomYis a new property that allows you to specifically set the vertical zoom factor of a Camera.- The
Camera.setZoommethod now allows you to pass two parameters:xandy, to control thezoomXandzoomYvalues accordingly. - The
Camera.zoomproperty now returns an average of thezoomXandzoomYproperties. Cameras.Scene2D.Events.FOLLOW_UPDATEis 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
roundPixelsset it will now round the internal scroll factors andworldViewduring thepreRenderstep. 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 (
inPositionandinColor), 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
calcMatrixproperty has been added, which Shape Game Objects use to maintain transform state during rendering. - The Graphics Pipeline no longer makes use of
tintEffector 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.setTexturehas 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.renderWebGLnow uses the standardGetCalcMatrixfunction, 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.renderTargetis a new property that contains aRenderTargetinstance, which is used for all drawing.- The
RenderTexture.framebufferproperty has been removed. You can now access this viaRenderTexture.renderTarget.framebuffer. - The
RenderTexture.glTextureproperty has been removed. You can now access this viaRenderTexture.renderTarget.texture. - The
RenderTexture.glproperty 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis a new method that will look-up and return a normal map for the given object.
Lights
Light.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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:
projIdentityhas been removed.projPersphas been removed.modelRotateXhas been removed.modelRotateYhas been removed.modelRotateZhas been removed.viewLoadhas been removed.viewRotateXhas been removed.viewRotateYhas been removed.viewRotateZhas been removed.viewScalehas been removed.viewTranslatehas been removed.modelIdentityhas been removed.modelScalehas been removed.modelTranslatehas been removed.viewIdentityhas been removed.viewLoad2Dhas been removed.projOrthohas been removed.
BitmapText - New Features, Updates and API Changes
BitmapText.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycoordinates. The character data includes the code, position, dimensions, and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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
setMaxWidthonDynamicBitmapText, 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_SCENEis 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_SCENEis 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_SCENEis 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_SCENEis 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.addedToSceneis 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.removedFromSceneis 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 theremovedFromScenemethod now. - The
Containerwill 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.eventsis a new property that references the Scene's Event Emitter. This is now used internally.DisplayList.addChildCallbackis a new method that overrides the List callback and fires the new ADDED events.DisplayList.removeChildCallbackis a new method that overrides the List callback and fires the new REMOVED events.GameObjectCreator.eventsis a new property that references the Scene's Event Emitter. This is now used internally.GameObjectFactory.eventsis a new property that references the Scene's Event Emitter. This is now used internally.ProcessQueue.checkQueueis a new boolean property that will make sure only unique objects are added to the Process Queue.- The
Update Listnow uses the newcheckQueueproperty to ensure no duplicate objects are on the active list. DOMElementFactory,ExternFactory,ParticleManagerFactor,RopeFactoryandSpriteFactoryall no longer add the objects to the Update List, this is now handled by the ADDED events instead.Sprite,Rope,ParticleEmitterManager,ExternandDOMElementnow all override theaddedToSceneandremovedFromScenecallbacks 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.
SpineContaineris a new Game Object available viathis.add.spineContainerto 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.runtimeswhich will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo intoplugins/spine/in order for this to work and then runnpm 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-zeroerror 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.setAnimationmethod will now use thetrackIndexparameter ifignoreIfPlayingis set and run the check against this track index. Fix #4842 (thanks @vinerz) - The
SpineFilewill 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
destroymethod 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.gameDestroyis a new method that is called if the Game instance emits adestroyevent. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.SpineFilewill 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)SpineFilenow 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.willRenderis no longer hard-coded to returntrue. 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
Animationclass no longer extendsEventEmitter, 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_KEYevents have been removed. Instead, please use the new events which all carry theframeKeyparameter, which can be used to handle frame specific events. The only exception to this isANIMATION_COMPLETE_KEY, which is a key specific version of the completion event. ANIMATION_UPDATE_EVENTis a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.ANIMATION_STOP_EVENTis a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of thestopmethods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)- The Game Object
Component.Animationcomponent has been renamed toAnimationStateand has moved namespace. It's now inPhaser.Animationsinstead ofGameObjects.Componentsto help differentiate it from theAnimationclass when browsing the documentation. - The
play,playReverse,playAfterDelay,playAfterRepeatandchainSprite and Animation Component methods can now all take aPhaser.Types.Animations.PlayAnimationConfigconfiguration object, as well as a string, as thekeyparameter. 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.createis 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.generateFrameNumbersis 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.generateFrameNamesis 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,playAfterDelayandplayAfterRepeatwill 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.skipMissedFramesis 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.addMixis 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.getMixis a new method that will return the mix duration between the two given animations.AnimationManager.removeMixis a new method that will remove the mixture between either two animations, or all mixtures for the given animation.AnimationState.removeis a new method that will remove a locally stored Animation instance from a Sprite.AnimationState.getis a new method that will return a locally stored Animation instance from the Sprite.AnimationState.existsis a new method that will check if a locally stored Animation exists on the Sprite.- The internal
AnimationState.removemethod has been renamed toglobalRemove. AnimationState.textureManageris a new property that references the global Texture Manager.AnimationState.animsis a new property that contains locally created Animations in a Custom Map.AnimationState.playandSprite.playno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.AnimationState.playReverseandSprite.playReverseno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.- The
AnimationState.delayedPlaymethod has been renamed toplayAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration. - The
AnimationState.stopOnRepeatmethod has been renamed tostopAfterRepeat - The
AnimationState.getCurrentKeymethod has been renamed togetName. AnimationState.getFrameNameis a new method that will return the key of the current Animation Frame, if an animation has been loaded.AnimationState.playAfterDelayandSprite.playAfterDelayare new methods that will play the given animation after the delay in ms expires.AnimationState.playAfterRepeatandSprite.playAfterRepeatare 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.chainmethod is now available on the Sprite class. - The
AnimationState.stopAfterDelaymethod is now available on the Sprite class. - The
AnimationState.stopAfterRepeatmethod is now available on the Sprite class. - The
AnimationState.stopOnFramemethod is now available on the Sprite class. AnimationManager.createFromAsepriteis 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.AnimationStatenow 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 optionalPlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.- The
PlayAnimationConfig.frameRateproperty lets you optionally override the animation frame rate. - The
PlayAnimationConfig.durationproperty lets you optionally override the animation duration. - The
PlayAnimationConfig.delayproperty lets you optionally override the animation delay. - The
PlayAnimationConfig.repeatproperty lets you optionally override the animation repeat counter. - The
PlayAnimationConfig.repeatDelayproperty lets you optionally override the animation repeat delay value. - The
PlayAnimationConfig.yoyoproperty lets you optionally override the animation yoyo boolean. - The
PlayAnimationConfig.showOnStartproperty lets you optionally override the animation show on start value. - The
PlayAnimationConfig.hideOnCompleteproperty lets you optionally override the animation hide on complete value. - The
PlayAnimationConfig.startFrameproperty lets you optionally set the animation frame to start on. - The
PlayAnimationConfig.timeScaleproperty lets you optionally set the animation time scale factor. AnimationState.delayCounteris a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animationSTARTevents fire. Fix #4426 (thanks @bdaenen)AnimationState.hasStartedis 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.showOnStartis a new boolean property that controls if the Game Object should havesetVisible(true)called on it when the animation starts.AnimationState.hideOnCompleteis a new boolean property that controls if the Game Object should havesetVisible(false)called on it when the animation completes.- The
AnimationState.chainmethod docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does! - The
AnimationState.setDelaymethod has been removed. It never actually worked and you can now perform the same thing by calling eitherplayAfterDelayor setting thedelayproperty in the play config. - The
AnimationState.getDelaymethod has been removed. You can now read thedelayproperty directly. - The
AnimationState.setRepeatmethod has been removed. You can achieve the same thing by setting therepeatproperty in the play config, or adjusting the publicrepeatCounterproperty if the animation has started. AnimationState.handleStartis a new internal private method that handles the animation start process.AnimationState.handleRepeatis a new internal private method that handles the animation repeat process.AnimationState.handleStopis a new internal private method that handles the animation stop process.AnimationState.handleCompleteis a new internal private method that handles the animation complete process.AnimationState.emitEventsis a new internal private method that emits animation events, cutting down on duplicate code.- The
AnimationState.restartmethod has a new optional boolean parameterresetRepeatswhich controls if you want to reset the repeat counter during the restart, or not. Animation.getTotalFramesis a new method that will return the total number of frames in the animation. You can access it viathis.anims.currentAnim.getTotalFramesfrom a Sprite.Animation.calculateDurationis a new method that calculates the duration, frameRate and msPerFrame for a given animation target.- The
BuildGameObjectAnimationfunction now uses thePlayAnimationConfigobject to set the values. Sprite.playReverseis a new method that allows you to play the given animation in reverse on the Sprite.Sprite.playAfterDelayis a new method that allows you to play the given animation on the Sprite after a delay.Sprite.stopis a new method that allows you to stop the current animation on the Sprite.AnimationManager.loadhas been removed as it's no longer required.AnimationManager.staggerPlayhas been fixed so you can now pass in negative stagger values.AnimationManager.staggerPlayhas a new optional boolean parameterstaggerFirst, which allows you to either include or exclude the first child in the stagger calculations.- The
Animation.completeAnimationmethod has been removed as it's no longer required. - The
Animation.loadmethod has been removed as it's no longer required. - The
Animation.setFramemethod has been removed as it's no longer required. - The
Animation.getFirstTickmethod has no longer needs theincludeDelayparameter, as it's handled byAnimationStatenow. - The
Animation.getFramesmethod has a new optional boolean parametersortFrameswhich will run a numeric sort on the frame names after constructing them, if a string-based frame is given. Types.Animations.Animationhas a new boolean propertysortFrames, which lets Phaser numerically sort the generated frames.AnimationState.timeScaleis a new public property that replaces the old private_timeScaleproperty.AnimationState.delayis a new public property that replaces the old private_delayproperty.AnimationState.repeatis a new public property that replaces the old private_repeatproperty.AnimationState.repeatDelayis a new public property that replaces the old private_repeatDelayproperty.AnimationState.yoyois a new public property that replaces the old private_yoyoproperty.AnimationState.inReverseis a new public property that replaces the old private_reverseproperty.AnimationState.startAnimationis a new public method that replaces the old private_startAnimationmethod.- The
AnimationState.getProgressmethod has been fixed so it will return correctly if the animation is playing in reverse. - The
AnimationState.globalRemovemethod will now always be called when an animation is removed from the global Animation Manager, not just once. - The
AnimationState.getRepeatmethod has now been removed. You can get the value from therepeatproperty. - The
AnimationState.setRepeatDelaymethod has now been removed. You can set the value using therepeatDelayconfig property, or changing it at run-time. AnimationState.completeis a new method that handles the completion in animation playback.- The
AnimationState.setTimeScalemethod has now been removed. You can set the value using thetimeScaleconfig property, or changing it at run-time. - The
AnimationState.getTimeScalemethod has now been removed. You can read the value using thetimeScaleproperty. - The
AnimationState.getTotalFramesmethod has been fixed and won't error if called when no animation is loaded. - The
AnimationState.setYoyomethod has now been removed. You can set the value using theyoyoconfig property, or changing it at run-time. - The
AnimationState.getYoyomethod has now been removed. You can read the value using theyoyoproperty. - The
AnimationState.stopAfterRepeatmethod now has an optional parameterrepeatCount, 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.updateFramemethod has now been removed. Everything is handled bysetCurrentFrameinstead, which removes one extra step out of the update process. GenerateFrameNameswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswould 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.GenerateFrameNumberscan now accept thestartandendparameters in reverse order, meaning you can now do{ start: 10, end: 1 }to create the animation in reverse.GenerateFrameNamescan now accept thestartandendparameters 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.createDynamicLayermethod has been renamed tocreateLayer. - The
Tilemap.createStaticLayermethod has been removed. UsecreateLayerinstead. - The
Tilemap.createBlankDynamicLayermethod has been renamed tocreateBlankLayer. - The
Tilemap.convertLayerToStaticmethod has been removed as it is no longer required. - The
TilemapLayerWebGLRendererfunction 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.TilemapOrientationTypeis a new type def that holds the 4 types of map orientation now supported.- The
Tile.updatePixelXYmethod now updates the tile XY position based on map type. ParseTilesetswill now correctly handle non-consecutive tile IDs. It also now correctly sets themaxIdproperty, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)Tilemap.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.LayerData.orientationis a new property that holds the tilemap layers orientation constant.LayerData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.MapData.orientationis a new property that holds the tilemap layers orientation constant.MapData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.Tilemaps.Components.HexagonalWorldToTileYis a new function that converts a world Y coordinate to hexagonal tile Y coordinate.Tilemaps.Components.StaggeredWorldToTileYis a new function that converts a world Y coordinate to staggered tile Y coordinate.Tilemaps.Components.HexagonalWorldToTileXYis a new function that converts world coordinates to hexagonal tile coordinates.Tilemaps.Components.IsometricWorldToTileXYis a new function that converts world coordinates to isometric tile coordinates.Tilemaps.Components.StaggeredWorldToTileXYis a new function that converts world coordinates to staggered tile coordinates.Tilemaps.Components.HexagonalTileToWorldYis a new function that converts a hexagonal Y coordinate to a world coordinate.Tilemaps.Components.StaggeredTileToWorldYis a new function that converts a staggered Y coordinate to a world coordinate.Tilemaps.Components.HexagonalTileToWorldXYis a new function that converts hexagonal tile coordinates to world coordinates.Tilemaps.Components.IsometricTileToWorldXYis a new function that converts isometric tile coordinates to world coordinates.Tilemaps.Components.StaggeredTileToWorldXYis a new function that converts staggered tile coordinates to world coordinates.Tilemaps.Components.GetTileToWorldXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldXXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetCullTilesFunctionis a new function that returns the correct culling function to use.Tilemaps.Components.HexagonalCullTilesis a new function that culls tiles in a hexagonal map.Tilemaps.Components.StaggeredCullTilesis a new function that culls tiles in a staggered map.Tilemaps.Components.IsometricCullTilesis a new function that culls tiles in a isometric map.Tilemaps.Components.CullBoundsis a new function that calculates the cull bounds for an orthogonal map.Tilemaps.Components.HexagonalCullBoundsis a new function that calculates the cull bounds for a hexagonal map.Tilemaps.Components.StaggeredCullBoundsis a new function that calculates the cull bounds for a staggered map.Tilemaps.Components.RunCullis a new function that runs the culling process from the combined bounds and tilemap.Tilemap._convertis a new internal private hash of tilemap conversion functions used by the public API.- The
Tilemap._isStaticCallmethod 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
GetTilesWithinWorldXYcomponent directly, saving lots of overhead. - The method
Tilemap.weightedRandomizehas changed so that the parameterweightedIndexesis now first in the method and is non-optional. Previously, it was the 5th parameter and incorrectly flagged as optional. - The method
TilemapLayer.weightedRandomizehas changed so that the parameterweightedIndexesis 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.Meshis 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.Vertexis a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.Geom.Mesh.Faceis a new class that consists of references to the threeVertexinstances that construct a single Face in a Mesh and provides methods for manipulating them.Geom.Mesh.GenerateVertsis a new function that will return an array ofVertexandFaceobjects 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.GenerateGridVertsis a new function that will generate a series ofVertexobjects in a grid format, based on the givenGenerateGridConfigconfig 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.GenerateObjVertsis a new function that will generate a series ofVertexobjects 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.ParseObjis a new function that will parse a triangulated Wavefront OBJ file into model data into a format that theGenerateObjVertsfunction can consume.Geom.Mesh.ParseObjMaterialis 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.RotateFaceis a new function that will rotate a Face by a given amount, based on an optional center of rotation.Loader.OBJFileis 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
MeshFactorysignatures have changed toscene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first.indiciesis a new parameter that allows you to provide indexed vertex data to create the Mesh from, where theindiciesarray holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. Theindiciesarray is optional. If your data is not indexed, then simply passnullor an empty array for this parameter. - The
MeshGame 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.addVerticesis 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.addVerticesFromObjis a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the newOBJFilewith athis.load.objcall, 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.hideCCWis 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.modelPositionis a new Vector3 property that allows you to translate the position of all vertices in the Mesh.Mesh.modelRotationis a new Vector3 property that allows you to rotate all vertices in the Mesh.Mesh.modelScaleis a new Vector3 property that allows you to scale all vertices in the Mesh.Mesh.panXis a new function that will translate the view position of the Mesh on the x axis.Mesh.panYis a new function that will translate the view position of the Mesh on the y axis.Mesh.panZis a new function that will translate the view position of the Mesh on the z axis.Mesh.setPerspectiveis a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.Mesh.setOrthois a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.Mesh.clearis a new method that will destroy all Faces and Vertices and clear the Mesh.Mesh.depthSortis a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.Mesh.addVertexis a new method that allows you to add a new single Vertex into the Mesh.Mesh.addFaceis a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.Mesh.getFaceCountnew is a new method that will return the total number of Faces in the Mesh.Mesh.getVertexCountnew is a new method that will return the total number of Vertices in the Mesh.Mesh.getFacenew is a new method that will return a Face instance from the Mesh based on the given index.Mesh.getFaceAtnew 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.verticesis now an array ofGameObject.Vertexinstances, not a Float32Array.Mesh.facesis a new array ofGameObject.Faceinstances, which is populated during a call to methods likeaddVerticesoraddModel.Mesh.totalRenderedis a new property that holds the total number of Faces that were rendered in the previous frame.Mesh.setDebugis 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
BringToTopto 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
MeshGame Object now extends theSingleAlphacomponent 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 standardsetAlphamethods. 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
colorsparameter in the constructor, factory method andaddVerticesmethod. 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
alphasparameter in the constructor, factory method andaddVerticesmethod. If a number, instead of an array, it will be used as the alpha for all vertices created. Mesh.debugGraphicis a new property that holds the debug Graphics instance reference.Mesh.debugCallbackis a new property that holds the debug render callback.Mesh.renderDebugVertsis a new method that acts as the default render callback forsetDebugif none is provided.Mesh.preDestroyis a new method that will clean-up the Mesh arrays and debug references on destruction.Mesh.isDirtyis a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically inpreUpdateto avoid generating lots of math when nothing has changed.- The
Mesh.uvarray has been removed. All UV data is now bound in the Vertex instances. - The
Mesh.colorsarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.alphasarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.tintFillproperty is now abooleanand defaults tofalse.
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.refreshis now called when theGame.READYevent 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
inputMouseCapturehas been removed, as this is now split into 3 new config options: inputMousePreventDefaultDownis a new config option that allows you to controlpreventDefaultcalls specifically on mouse down events. Set it viainput.mouse.preventDefaultDownin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultUpis a new config option that allows you to controlpreventDefaultcalls specifically on mouse up events. Set it viainput.mouse.preventDefaultUpin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultMoveis a new config option that allows you to controlpreventDefaultcalls specifically on mouse move events. Set it viainput.mouse.preventDefaultMovein the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultWheelis a new config option that allows you to controlpreventDefaultcalls specifically on mouse wheel events. Set it viainput.mouse.preventDefaultWheelin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.- The
MouseManager.captureproperty has been removed, as this is now split into 3 new config options (see below) MouseManager.preventDefaultDownis a new boolean property, set via theinputMousePreventDefaultDownconfig option that allows you to toggle capture of mouse down events at runtime.MouseManager.preventDefaultUpis a new boolean property, set via theinputMousePreventDefaultUpconfig option that allows you to toggle capture of mouse up events at runtime.MouseManager.preventDefaultMoveis a new boolean property, set via theinputMousePreventDefaultMoveconfig option that allows you to toggle capture of mouse move events at runtime.MouseManager.preventDefaultWheelis a new boolean property, set via theinputMousePreventDefaultWheelconfig option that allows you to toggle capture of mouse wheel at runtime.- In the
MouseManagerthe 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
GamepadPluginwill now callrefreshPadsas 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 viathis.input.gamepad.pad1and 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._createdis 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.downwill 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
useHandCursorenabled, 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.shutdownmethod 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.processOverEventshas 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.tintTopLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTLwhich has now been removed.Tint.tintTopRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTRwhich has now been removed.Tint.tintBottomLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBLwhich has now been removed.Tint.tintBottomRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBRwhich has now been removed.- The property
Tint._isTintedhas been removed as it's no longer required. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they now read the color value asoutTint.bgrinstead ofoutTint.rgb. This allows the colors to remain in RGB order within the Tint component. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they no longer have a 3-way check on theoutTintEffectvalue. - The
Multi Pipeline,Bitmap Text,Render Texture,Text,TileSpriteandCameranow all read the tint values from the public properties instead of the private_tintTLetc ones. They also now set thetintEffectvalue directly from thetintFillproperty, removing another conditional check. - The function
GetColorFromValuehas been removed as it's no longer used internally. - The
Rope.tintFillproperty is now a boolean, not an integer, and can no longer take2as 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
getTintAppendFloatAlphaAndSwaphave been replaced withgetTintAppendFloatAlphainstead. - As a result of the change to the shader, the Multi Pipeline now uses the
WebGLRenderer.whiteTextureandtintEffectmode 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.whiteTextureis 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
TextureManagernow generates a new texture with the key__WHITEdurings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines. Config.images.whiteis 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
Bodyclass has a new boolean propertypushable(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.setPushableis a new chainable method that allows you to set thepushablestate of a Body.Arcade.Components.Pushableis 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.disableUpdateis a new method that will prevent the Arcade Physics Worldupdatemethod 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.enableUpdateis 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.customUpdateis a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. Iftruethe World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)Physics.Arcade.Body.setCollideWorldBoundsnow has a new optional parameteronWorldBoundswhich allows you to enable the Body'sonWorldBoundsproperty in the same call (thanks @samme)ArcadePhysics.Body.setMaxVelocityXis a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)ArcadePhysics.Body.setMaxVelocityYis a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)- The
PhysicsGroupconfig now has two new optional propertiesmaxVelocityXandmaxVelocityYwhich allows you to set the maximum velocity on bodies added to the Group (thanks @samme) - The
Arcade.Body.resetFlagsmethod has a new optional boolean parameterclear. If set, it clears thewasTouchingflags on the Body. This happens automatically whenBody.resetis called. Previous to this, the flags were not reset until the next physics step (thanks @samme) Physics.Arcade.ProcessXis a new set of functions, called by theSeparateXfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Physics.Arcade.ProcessYis a new set of functions, called by theSeparateYfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Arcade.Body.centervalues 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_STEPevent now has a new parameter: the delta argument (thanks @samme) - The Arcade Body
dragproperty 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 usedragyou will need to change any existing drag values to get the same effects as before. Convertdragtodrag ^ 60ordrag ^ fpsif 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.
AtlasJSONFileno longer stores the JSON in the JSON Cache once the texture has been created.AtlasXMLFileno longer stores the XML in the XML Cache once the texture has been created.UnityAtlasFileno longer stores the Text in the Text Cache once the texture has been created.BitmapFontFileno longer stores the XML in the XML Cache once the texture has been created.- You can now use
TextureManager.removeto 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.ColorMatrixis 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.setmethod allows you to set the values of a ColorMatrix. - The
ColorMatrix.resetmethod will reset the ColorMatrix to its default values. - The
ColorMatrix.getDatamethod will return the data in the ColorMatrix as a Float32Array, useful for setting in a shader uniform. - The
ColorMatrix.brightnessmethod lets you set the brightness of the ColorMatrix. - The
ColorMatrix.saturatemethod lets you set the saturation of the ColorMatrix. - The
ColorMatrix.desaturatemethod lets you desaturate the colors in the ColorMatrix. - The
ColorMatrix.huemethod lets you rotate the hues of the ColorMatrix by the given amount. - The
ColorMatrix.grayscalemethod converts the ColorMatrix to grayscale. - The
ColorMatrix.blackWhitemethod converts the ColorMatrix to black and whites. - The
ColorMatrix.contrastmethod lets you set the contrast of the ColorMatrix. - The
ColorMatrix.negativemethod converts the ColorMatrix to negative values. - The
ColorMatrix.desaturateLuminancemethod applies a desaturated luminance to the ColorMatrix. - The
ColorMatrix.sepiamethod applies a sepia tone to the ColorMatrix. - The
ColorMatrix.nightmethod applies a night time effect to the ColorMatrix. - The
ColorMatrix.lsdmethod applies a trippy color effect to the ColorMatrix. - The
ColorMatrix.brownmethod applies a brown tone to the ColorMatrix. - The
ColorMatrix.vintagePinholemethod applies a vintage pinhole color effect to the ColorMatrix. - The
ColorMatrix.kodachromemethod applies a kodachrome color effect to the ColorMatrix. - The
ColorMatrix.technicolormethod applies a technicolor color effect to the ColorMatrix. - The
ColorMatrix.polaroidmethod applies a polaroid color effect to the ColorMatrix. - The
ColorMatrix.shiftToBGRmethod shifts the values of the ColorMatrix into BGR order. - The
ColorMatrix.multiplymethod 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#RESIZEevent no longer sends theresolutionas a parameter. - The
BaseCamera.resolutionproperty has been removed. - The internal private
BaseCamera._cx,_cy,_cwand_chproperties has been removed, usex,y,widthandheightinstead. - The
BaseCamera.preRendermethod no longer receives or uses theresolutionparameter. - The
Camera.preRendermethod no longer receives or uses theresolutionparameter. - The
CameraManager.onResizemethod no longer receives or uses theresolutionparameter. - The
Core.Config.resolutionproperty has been removed. - The
TextStyle.resolutionproperty 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
CanvasRendererno longer reads or uses the Game Config resolution property. - The
PipelineManager.resizemethod along withWebGLPipeline.resizeand anything else that extends them no longer receives or uses theresolutionparameter. - The
WebGLRenderer.resizeandonResizemethods no longer receives or uses theresolutionparameter. - The
ScaleManager.resolutionproperty 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.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Intersects.GetLineToPointsis 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.GetRaysFromPointToPolygonis 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.Translateis a new function that allows you to translate all the points of a polygon by the given values.Geom.Polygon.Simplifyis 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.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.getTweensOfhas a new parameterincludePending. 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.hasBootedis 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 theWebGLRenderer.addPipelinemethod, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)- The WebGL Renderer will now add the pipelines during the
bootmethod, instead ofinit. - You can now use
this.rendererfrom within a Scene, as it's now a Scene-level property and part of the Injection Map. Clock.addEventcan now take an existingTimerEventobject, as well as a config object. If aTimerEventis 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.removeEventis a new method that allows you to remove aTimerEvent, or an array of them, from all internal lists of the current Clock.Group.getMatchingis a new method that will return any members of the Group that match the given criteria, such asgetMatching('visible', true)(thanks @atursams)Utils.Array.SortByDigitsis 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 callingGroup.createMultipleorGroup.createFromConfig, can now accept the following new properties:setOrigin: { x, y, stepX, stepY }which are applied to the items created by the Group.Transform.copyPositionis a new method that will copy the position from the given object to the Game Object (thanks @samme)- The
Text.MeasureTextfunction, 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 newactualBoundingBoxAscentfunctions 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.GetCalcMatrixis 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,StarandTriangle. This dramatically reduces the amount of duplicate code across the API.Utils.Array.Matrix.Translateis a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.Vertor3.addScaleis 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
easeParamsin the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh) BitmapMask.createMaskis 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.clearMaskwill 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.Quaternionnow has a new propertyonChangeCallbackwhich, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.- The
Quaternion.setmethod has a new optional boolean parameterupdate(defaults totrue), which will call theonChangeCallbackif set. Quaternion.setFromEuleris a new method that will set the quaternion from the givenEulerobject, optionally calling theonChangeCallbackin the process.Quaternion.setFromRotationMatrixis a new method that will set the rotation of the quaternion from the given Matrix4.Vector3.setFromMatrixPositionis a new method that will set the components of the Vector3 based on the position of the given Matrix4.Vector3.setFromMatrixColumnis a new method that will set the components of the Vector3 based on the specified Matrix4 column.Vector3.fromArrayis a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.Vector3.minis a new method that will set the components of the Vector3 based on theMain.minbetween it and the given Vector3.Vector3.maxis a new method that will set the components of the Vector3 based on theMain.maxbetween it and the given Vector3.Vector3.addVectorsis a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.Vector3.addScalaris a new method that will multiply the components of the Vector3 by the scale value given.Vector3.applyMatrix3is a new method that will take a Matrix3 and apply it to the Vector3.Vector3.applyMatrix4is a new method that will take a Matrix4 and apply it to the Vector3.Vector3.projectViewMatrixis a new method that multiplies the Vector3 by the given view and projection matrices.Vector3.unprojectViewMatrixis a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.Matrix4.setValuesis a new method that allows you to set all of the matrix components individually. Most internal methods now use this.Matrix.multiplyToMat4is a new method that multiplies a Matrix4 by the givensrcMatrix4 and stores the results in theoutMatrix4.Matrix4.fromRotationXYTranslationis a new method that takes the rotation and position vectors and builds this Matrix4 from them.Matrix4.getMaxScaleOnAxisis a new method that will return the maximum axis scale from the Matrix4.Matrix4.lookAtRHis a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.Matrix4.transformis a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.Matrix4.multiplyMatricesis a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.Matrix4.premultiplyis a new method that takes a Matrix4 and multiplies it by the current Matrix4.Matrix4.getInverseis a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.CameraManager.getVisibleChildrenis a new method that is called internally by theCameraManager.rendermethod. It filters the DisplayList, so that Game Objects that pass thewillRendertest 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.setDampingis a new method that allows you to set theuseDampingproperty of a Body in a chainable way. Fix #5352 (thanks @juanitogan)- The
GameObjects.Graphics.fillGradientStylemethod 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.PipelineConfigis a new configuration object that you can set in the Game Config under thepipelineproperty. 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 thepipelineobject, or set it under therendersub-config.Utils.Object.DeepCopyis a new function that will recursively deep copy an array of object.Time.TimerEvent.getRemainingis a new method that returns the time interval until the next iteration of the Timer Event (thanks @samme)Time.TimerEvent.getRemainingSecondsis a new method that returns the time interval until the next iteration of the Timer Event in seconds (thanks @samme)Time.TimerEvent.getOverallRemainingis a new method that returns the time interval until the last iteration of the Timer Event (thanks @samme)Time.TimerEvent.getOverallRemainingSecondsis a new method that returns the time interval until the last iteration of the Timer Event in seconds (thanks @samme)GameObjects.Video.loadMediaStreamis 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.ColorSpectrumis 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.AsepriteFileis 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 viathis.load.asesprite(png, json).GameObject.displayListis 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.Earcutand is fully documented. Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself. - The constant
Phaser.Renderer.WebGL.BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.FLOATvalue has been removed as it wasn't used internally. Pointer.downTimenow 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.upTimenow 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.getDurationmethod now uses the new PointerdownTimeandupTimevalues, 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
BaseShaderdefault vertex shader now includes theoutTexCoordvec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok) - When using the
GameObjectCreatorforContainersyou can now specify thechildrenproperty in the configuration object. Textures.Parsers.JSONHashwill now perform ahasOwnPropertycheck when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes fromJSON.parse. Fix #4768 (thanks @RollinSafary)- The
Camera3DPlugin 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.seekwill 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
inputWindowEventsis set in the Game Config, then theMouseManagerwill now listen for the events onwindow.topinstead of justwindow, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in atry/catchblock, as not all sites allow access towindow.top(specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow) MouseManager.isTopis a new boolean read-only property that flags if the mouse event listeners were attached towindow.top(true), or justwindow(false). By default Phaser will attemptwindow.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back towindowin those cases and set this property to false (thanks BunBunBun)Types.GameObjects.Text.GetTextSizeObjectis a new type def for the GetTextSize function results.Utils.Array.StableSorthas 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. Theinplacefunction has been removed, just callStableSort(array)directly now. All classes that usedStableSort.inplacehave 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.setOriginwill now callupdateDisplayOriginon the items array, otherwise the effects can't be seen when rendering.- You can now set the
ArcadeWorld.fixedStepproperty via theArcadeWorldConfigobject (thanks @samme) Utils.Array.NumerArraycan now accept thestartandendparameters in reverse order, i.e.10, 1will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.DataManager.Events.DESTROYis a new event that the Data Manager will listen for from its parent and then call its owndestroymethod when received.- The
Quaternionclass constructor will now default the values to0,0,0,1if they're not provided, making it an identity quaternion, rather than the0,0,0,0it was before. - You can now set the
ParticleEmitter.reservevalue via the emitter configuration object (thanks @vforsh) - Setting the
pixelArtconfig option will now setantialiasGLtofalse, as well asantialias. Fix #5309 (thanks @Vegita2) - The
Shapeclass now includes theComputedSizecomponent properties and methods directly in the class, rather than applying as a mixin.setSizeis now flagged as beingprivate, 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.maxParallelDownloadsvalue is now set to 6 if running on Android, or 32 on any other OS. This avoidsnet::ERR_FAILEDissues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary) - When running an Arcade Physics
overlaptest against aStaticBody, it will no longer set theblockedstates 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
LineGame 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
Quaternionclass now has 4 new private properties:_x,_y,_zand_wand 4 new getters and setters for the public versions. It also now passes most methods viasetto allow for the onChange callback to be invoked. This does not change the public-facing API. Groupnow extendsEventEmitter, allowing you to emit custom events from within a Group.Device.Audio.wavnow usesaudio/wavas thecanPlayTypecheck string, instead ofaudio/wav; codecs="1", which should allow iOS13 to play wav files again.- In the
Loader.FileTypes.TextFileconfig you can now override the type and cache destination for the file. Loader.MultiFilewill 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.tintvalue is now0xffffff(previously, it was0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh) SceneManager.startwill now reset theSceneSystems.sceneUpdatereference toNOOP. This gets set back to the Scene update method again duringbootScene(if it has one) and stops errors with external plugins and multi-part files that may triggerupdatebeforecreatehas been called. Fix #4629 (thanks @Osmose)Phaser.Scene.rendereris a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.- The
CanvasRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead. - Since iOS 13, iPads now identify as MacOS devices. A new maxTouchPoint check is now part of the
Device.OStests, stopping iPads from being flagged as desktop devices. Fix #5389 (thanks @SBCGames) - The
BitmapMask.prevFramebufferproperty has been removed as it's no longer required, due to the fbo stack in the renderer. - The
TextureManager.addGLTexturemethod has been updated so that thewidthandheightparameters are now optional. If not provided, and if available, they will be read from the given WebGLTexture instead (thanks @hexus) GameObjects.Components.Depth.depthListis 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 fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.RenderTexture.fillwould 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
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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
ProcessQueuewas emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar) - The
GridAlignaction didn't work if only theheightparameter was set. Fix #5019 (thanks @halilcakar) - The
Color.HSVToRGBfunction has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX) - Previously, the
easeParamsarray within a Tweenspropsobject, 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.setRenderToTextureitszoomandrotationvalues would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok) GameObjects.Shape.Gridwould render a white fill even if you passedundefinedas the fill color in the constructor. It now doesn't render cells if no fill color is given.- The
onMouseevents in the Input Manager didn't reset theactivePointerproperty 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
GetScreenOrientationfunction will now check forwindow.orientationfirst, 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 emitorientationchangeevents correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu) Time.Clock.addEventcan now take an instance of aTimerEventas its parameter. Fix #5294 (thanks @samme @EmilSV)GameConfig.audionow defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)- The
Loader.pathwas 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.getMatchingwould always return an empty array. It now returns matching children (thanks @samme)- The
ParticleManagerWebGLRenderernow 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
ParticleManagerCanvasRenderernow calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also usessetToContextinternally. 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
GraphicsWebGL Renderer will now default topathOpen = true. This fixes issues under WebGL where, for example, adding an arc and callingstrokePath, without first callingbeginPathwill no longer cause rendering artefacts when WebGL tries to close the path with a single tri. Graphics.strokeRoundedRectnow issuesmoveTocommands 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
snapshotin WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in theWebGLSnapshotfunction. Fix #4956 (thanks @gammafp @telinc1) - You can now draw a
Groupto aRenderTexture. Previously, it failed to pass the camera across, resulting in none of the Group children being drawn. Fix #5330 (thanks @somnolik) Particles.EmitterOp.setMethodswill now reset bothonEmitandonUpdateto 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.EmitterOpnow cleanly separates between the different types of property configuration options.start | endwill now ease between the two values,min | maxwill pick a random value between them andrandom: []will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)- When setting both
transparent: trueandbackgroundColorin 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
EllipseGame Object now will update the width, height, and geometric position in thesetSizemethod (thanks @PhaserEditor2D) - When measuring the last word in a line in a
TextGame Object, it no longer adds extra white space to the end (thanks @rexrainbow) Utils.Array.Removewould 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.TriangleToLinewouldn't returntrueif 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.MoveTofunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.DOM.GetInnerHeightfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Bobclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsManagerclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsPluginclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Particles.EmitterOpclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.GetTextSizefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.MeasureTextfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.TextStylefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Input.CreatePixelPerfectHandlerfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapCircfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapRectfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Tilemapnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Componentsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.MatterGameObjectclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.PointerConstraintclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetPhysicsPluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetScenePluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Structs.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Tilemaps.Parsers.Tiledfunction has now been exposed on the Phaser namespace (thanks @samme) - Every single
Tilemap.Componentfunction 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:
TextureTintPipelineis now called theMultiPipeline.TextureTintStripPipelineis now called theRopePipeline.ForwardDiffuseLightPipelineis now called theLightPipeline.
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.fragis now calledLight.frag.TextureTint.fragis now calledMulti.frag.TextureTint.vertis now calledMulti.vert.
Other pipeline changes are as follows:
- None of the shaders or pipelines use the
uViewMatrixanduModelMatrixuniforms 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.WebGLPipelineConfigis a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.Types.Renderer.WebGL.WebGLPipelineAttributesConfigis 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
rendererproperty automatically, so it's no longer required in the config. - All pipelines will now work out the
glproperty automatically, so it's no longer required in the config. - All pipelines will now extract the
nameproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexCapacityproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexSizeproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexDataproperty from the config, allowing you to set it externally. - All pipelines will now extract the
attributesproperty from the config, allowing you to set it externally. - All pipelines will now extract the
topologyproperty from the config, allowing you to set it externally. - The
WebGLPipeline.shouldFlushmethod now accepts an optional parameteramount. If given, it will returntrueif 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
RopePipelinenow extendsMultiPipelineand just changes the topolgy, vastly reducing the filesize. - The
WebGLPipeline.flushLockedproperty 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.setPipelinemethod, 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.set1fwill set a 1f uniform based on the given name.WebGLPipeline.set2fwill set a 2f uniform based on the given name.WebGLPipeline.set3fwill set a 3f uniform based on the given name.WebGLPipeline.set4fwill set a 4f uniform based on the given name.WebGLPipeline.set1fvwill set a 1fv uniform based on the given name.WebGLPipeline.set2fvwill set a 2fv uniform based on the given name.WebGLPipeline.set3fvwill set a 3fv uniform based on the given name.WebGLPipeline.set4fvwill set a 4fv uniform based on the given name.WebGLPipeline.set1ivwill set a 1iv uniform based on the given name.WebGLPipeline.set2ivwill set a 2iv uniform based on the given name.WebGLPipeline.set3ivwill set a 3iv uniform based on the given name.WebGLPipeline.set4ivwill set a 4iv uniform based on the given name.WebGLPipeline.set1iwill set a 1i uniform based on the given name.WebGLPipeline.set2iwill set a 2i uniform based on the given name.WebGLPipeline.set3iwill set a 3i uniform based on the given name.WebGLPipeline.set4iwill set a 4i uniform based on the given name.WebGLPipeline.setMatrix2fvwill set a matrix 2fv uniform based on the given name.WebGLPipeline.setMatrix3fvwill set a matrix 3fv uniform based on the given name.WebGLPipeline.setMatrix4fvwill 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.setFloat1has been removed. Please useset1finstead.WebGLPipeline.setFloat2has been removed. Please useset2finstead.WebGLPipeline.setFloat3has been removed. Please useset3finstead.WebGLPipeline.setFloat4has been removed. Please useset4finstead.WebGLPipeline.setFloat1vhas been removed. Please useset1fvinstead.WebGLPipeline.setFloat2vhas been removed. Please useset2fvinstead.WebGLPipeline.setFloat3vhas been removed. Please useset3fvinstead.WebGLPipeline.setFloat4vhas been removed. Please useset4fvinstead.WebGLPipeline.setInt1has been removed. Please useset1iinstead.WebGLPipeline.setInt2has been removed. Please useset2iinstead.WebGLPipeline.setInt3has been removed. Please useset3iinstead.WebGLPipeline.setInt4has been removed. Please useset4iinstead.WebGLPipeline.setMatrix1has been removed. Please usesetMatrix2fvinstead.WebGLPipeline.setMatrix2has been removed. Please usesetMatrix3fvinstead.WebGLPipeline.setMatrix3has been removed. Please usesetMatrix4fvinstead.
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.pipelinesis no longer a plain object containing pipeline instances. It's now an instance of thePipelineManagerclass. This instance is created during the init and boot phase of the renderer.- The
WebGLRenderer.currentPipelineproperty no longer exists, instead usePipelineManager.current. - The
WebGLRenderer.previousPipelineproperty no longer exists, instead usePipelineManager.previous. - The
WebGLRenderer.hasPipelinemethod no longer exists, instead usePipelineManager.has. - The
WebGLRenderer.getPipelinemethod no longer exists, instead usePipelineManager.get. - The
WebGLRenderer.removePipelinemethod no longer exists, instead usePipelineManager.remove. - The
WebGLRenderer.addPipelinemethod no longer exists, instead usePipelineManager.add. - The
WebGLRenderer.setPipelinemethod no longer exists, instead usePipelineManager.set. - The
WebGLRenderer.rebindPipelinemethod no longer exists, instead usePipelineManager.rebind. - The
WebGLRenderer.clearPipelinemethod no longer exists, instead usePipelineManager.clear.
The Pipeline Manager also offers the following new features:
- The
PipelineManager.resizemethod automatically handles resize events across all pipelines. - The
PipelineManager.preRendermethod calls the pre-render method of all pipelines. - The
PipelineManager.rendermethod calls the render method of all pipelines. - The
PipelineManager.postRendermethod calls the post-render method of all pipelines. - The
PipelineManager.setMultimethod automatically binds the Multi Texture Pipeline, Phaser's default. - The
PipelineManager.clearmethod will clear the pipeline, store it inpreviousand free the renderer. - The
PipelineManager.rebindmethod will reset the rendering context and restore thepreviouspipeline, if set.
New constants have been created to help you reference a pipeline without needing to use strings:
Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINEfor the Bitmap Mask Pipeline.Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINEfor the Light 2D Pipeline.Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINEfor the Single Pipeline.Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINEfor the Multi Pipeline.Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINEfor 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture that was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLPipeline.forceZerois a new property that informs Game Objects if the pipeline requires a zero bound texture unit.WebGLPipeline.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLRenderer.unbindTexturesis a new method that will activate and then null bind all WebGL textures.Renderer.WebGL.Utils.parseFragmentShaderMaxTexturesis 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.getComponentCountfunction has been removed as this is no longer required internally.
WebGLRenderer New Features, Updates and API Changes
WebGLRenderer.instancedArraysExtensionis a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.WebGLRenderer.vaoExtensionis a new property that holds a reference to the Vertex Array Object WebGL Extension, if supported by the browser.WebGLRenderer.resetProgramis a new method that will rebind the current program, without flushing or changing any properties.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.WebGLRenderer.finalTypeis a new boolean property that signifies if the current Game Object being rendered is the final one in the list.- The
WebGLRenderer.updateCanvasTexturemethod will now setgl.UNPACK_PREMULTIPLY_ALPHA_WEBGLto 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.previousPipelineis a new property that is set during a call toclearPipelineand used during calls torebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.- The
WebGLRenderer.rebindPipelinemethod has been changed slightly. Previously, you had to specify thepipelineInstance, but this is now optional. If you don't, it will use the newpreviousPipelineproperty instead. If not set, or none given, it will now return without throwing gl errors as well. WebGLRenderer.defaultScissoris a new property that holds the default scissor dimensions for the renderer. This is modified duringresizeand avoids continuous array generation in thepreRenderloop.- The
WebGLRenderer.nativeTexturesarray has been removed and any WebGLTextures created by the renderer are no longer stored within it. All WebGLTexture instances are stored in theTextureSourceobjects anyway, or by local classes such as RenderTexture, so there was no need to have another array taking up memroy. - The
WebGLRenderer.deleteTexturemethod has a new optional boolean parameterresetwhich allows you to control if theWebGLRenderer.resetTexturesmethod is called, or not, after the texture is deleted. - The
WebGLRenderer.getMaxTexturesmethod has been removed. This is no longer needed as you can use theWebGLRenderer.maxTexturesproperty instead. - The
WebGLRenderer.setProgrammethod now returns a boolean.trueif the program was set, otherwisefalse. - The
WebGLRenderer.setVertexBuffermethod now returns a boolean.trueif the buffer was set, otherwisefalse. WebGLRenderer.setFloat1has been removed. UseWebGLPipeline.set1forWebGLShader.set1finstead.WebGLRenderer.setFloat2has been removed. UseWebGLPipeline.set2forWebGLShader.set2finstead.WebGLRenderer.setFloat3has been removed. UseWebGLPipeline.set3forWebGLShader.set3finstead.WebGLRenderer.setFloat4has been removed. UseWebGLPipeline.set4forWebGLShader.set4finstead.WebGLRenderer.setFloat1vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set1fvinstead.WebGLRenderer.setFloat2vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set2fvinstead.WebGLRenderer.setFloat3vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set3fvinstead.WebGLRenderer.setFloat4vhas been removed. UseWebGLPipeline.set1fvorWebGLShader.set4fvinstead.WebGLRenderer.setInt1has been removed. UseWebGLPipeline.set1fiorWebGLShader.set1iinstead.WebGLRenderer.setInt2has been removed. UseWebGLPipeline.set1fiorWebGLShader.set2iinstead.WebGLRenderer.setInt3has been removed. UseWebGLPipeline.set1fiorWebGLShader.set3iinstead.WebGLRenderer.setInt4has been removed. UseWebGLPipeline.set1fiorWebGLShader.set4iinstead.WebGLRenderer.setMatrix2has been removed. UseWebGLPipeline.setMatrix2fvorWebGLShader.setMatrix2fvinstead.WebGLRenderer.setMatrix3has been removed. UseWebGLPipeline.setMatrix3fvorWebGLShader.setMatrix3fvinstead.WebGLRenderer.setMatrix4has been removed. UseWebGLPipeline.setMatrix4fvorWebGLShader.setMatrix4fvinstead.- The
WebGLRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead. WebGLRenderer.fboStackis a new property that maintains a stack of framebuffer objects, used for pipelines supporting multiple render targets.WebGLRenderer.pushFramebufferis 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 ofsetFramebuffer. Remember to callpopFramebufferafter using it.WebGLRenderer.popFramebufferis a new method that will pop the current framebuffer off the fbo stack and set the previous one as being active.WebGLRenderer.setFramebufferhas a new optional boolean parameterresetTextureswhich will reset the WebGL Textures, if set totrue(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.renderToTextureproperty has been removed. Effects are now handled via pipelines. - The
Camera.renderToGameproperty has been removed. Effects are now handled via pipelines. - The
Camera.canvasproperty has been removed. Textures are handled by pipelines. - The
Camera.contextproperty has been removed. Textures are handled by pipelines. - The
Camera.glTextureproperty has been removed. GL Textures are handled by pipelines. - The
Camera.framebufferproperty has been removed. GL Framebuffers are handled by pipelines. - The
Camera.setRenderToTexturemethod has been removed. Effects are now handled via pipelines. - The
Camera.clearRenderToTexturemethod 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_UPDATEis 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
roundPixelsset it will now round the internal scroll factors andworldViewduring thepreRenderstep. 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 (
inPositionandinColor), 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
calcMatrixproperty has been added, which Shape Game Objects use to maintain transform state during rendering. - The Graphics Pipeline no longer makes use of
tintEffector 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.setTexturehas 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.renderWebGLnow uses the standardGetCalcMatrixfunction, 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis a new method that will look-up and return a normal map for the given object.
Lights
Light.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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:
projIdentityhas been removed.projPersphas been removed.modelRotateXhas been removed.modelRotateYhas been removed.modelRotateZhas been removed.viewLoadhas been removed.viewRotateXhas been removed.viewRotateYhas been removed.viewRotateZhas been removed.viewScalehas been removed.viewTranslatehas been removed.modelIdentityhas been removed.modelScalehas been removed.modelTranslatehas been removed.viewIdentityhas been removed.viewLoad2Dhas been removed.projOrthohas been removed.
BitmapText - New Features, Updates and API Changes
BitmapText.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycoordinates. The character data includes the code, position, dimensions, and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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
setMaxWidthonDynamicBitmapText, 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_SCENEis 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_SCENEis 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_SCENEis 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_SCENEis 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.addedToSceneis 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.removedFromSceneis 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 theremovedFromScenemethod now. - The
Containerwill 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.eventsis a new property that references the Scene's Event Emitter. This is now used internally.DisplayList.addChildCallbackis a new method that overrides the List callback and fires the new ADDED events.DisplayList.removeChildCallbackis a new method that overrides the List callback and fires the new REMOVED events.GameObjectCreator.eventsis a new property that references the Scene's Event Emitter. This is now used internally.GameObjectFactory.eventsis a new property that references the Scene's Event Emitter. This is now used internally.ProcessQueue.checkQueueis a new boolean property that will make sure only unique objects are added to the Process Queue.- The
Update Listnow uses the newcheckQueueproperty to ensure no duplicate objects are on the active list. DOMElementFactory,ExternFactory,ParticleManagerFactor,RopeFactoryandSpriteFactoryall no longer add the objects to the Update List, this is now handled by the ADDED events instead.Sprite,Rope,ParticleEmitterManager,ExternandDOMElementnow all override theaddedToSceneandremovedFromScenecallbacks 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.
SpineContaineris a new Game Object available viathis.add.spineContainerto 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.runtimeswhich will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo intoplugins/spine/in order for this to work and then runnpm 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-zeroerror 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.setAnimationmethod will now use thetrackIndexparameter ifignoreIfPlayingis set and run the check against this track index. Fix #4842 (thanks @vinerz) - The
SpineFilewill 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
destroymethod 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.gameDestroyis a new method that is called if the Game instance emits adestroyevent. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.SpineFilewill 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)SpineFilenow 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.willRenderis no longer hard-coded to returntrue. 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
Animationclass no longer extendsEventEmitter, 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_KEYevents have been removed. Instead, please use the new events which all carry theframeKeyparameter, which can be used to handle frame specific events. The only exception to this isANIMATION_COMPLETE_KEY, which is a key specific version of the completion event. ANIMATION_UPDATE_EVENTis a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.ANIMATION_STOP_EVENTis a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of thestopmethods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)- The Game Object
Component.Animationcomponent has been renamed toAnimationStateand has moved namespace. It's now inPhaser.Animationsinstead ofGameObjects.Componentsto help differentiate it from theAnimationclass when browsing the documentation. - The
play,playReverse,playAfterDelay,playAfterRepeatandchainSprite and Animation Component methods can now all take aPhaser.Types.Animations.PlayAnimationConfigconfiguration object, as well as a string, as thekeyparameter. 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.createis 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.generateFrameNumbersis 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.generateFrameNamesis 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,playAfterDelayandplayAfterRepeatwill 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.skipMissedFramesis 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.addMixis 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.getMixis a new method that will return the mix duration between the two given animations.AnimationManager.removeMixis a new method that will remove the mixture between either two animations, or all mixtures for the given animation.AnimationState.removeis a new method that will remove a locally stored Animation instance from a Sprite.AnimationState.getis a new method that will return a locally stored Animation instance from the Sprite.AnimationState.existsis a new method that will check if a locally stored Animation exists on the Sprite.- The internal
AnimationState.removemethod has been renamed toglobalRemove. AnimationState.textureManageris a new property that references the global Texture Manager.AnimationState.animsis a new property that contains locally created Animations in a Custom Map.AnimationState.playandSprite.playno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.AnimationState.playReverseandSprite.playReverseno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.- The
AnimationState.delayedPlaymethod has been renamed toplayAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration. - The
AnimationState.stopOnRepeatmethod has been renamed tostopAfterRepeat - The
AnimationState.getCurrentKeymethod has been renamed togetName. AnimationState.getFrameNameis a new method that will return the key of the current Animation Frame, if an animation has been loaded.AnimationState.playAfterDelayandSprite.playAfterDelayare new methods that will play the given animation after the delay in ms expires.AnimationState.playAfterRepeatandSprite.playAfterRepeatare 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.chainmethod is now available on the Sprite class. - The
AnimationState.stopAfterDelaymethod is now available on the Sprite class. - The
AnimationState.stopAfterRepeatmethod is now available on the Sprite class. - The
AnimationState.stopOnFramemethod is now available on the Sprite class. AnimationManager.createFromAsepriteis 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.AnimationStatenow 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 optionalPlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.- The
PlayAnimationConfig.frameRateproperty lets you optionally override the animation frame rate. - The
PlayAnimationConfig.durationproperty lets you optionally override the animation duration. - The
PlayAnimationConfig.delayproperty lets you optionally override the animation delay. - The
PlayAnimationConfig.repeatproperty lets you optionally override the animation repeat counter. - The
PlayAnimationConfig.repeatDelayproperty lets you optionally override the animation repeat delay value. - The
PlayAnimationConfig.yoyoproperty lets you optionally override the animation yoyo boolean. - The
PlayAnimationConfig.showOnStartproperty lets you optionally override the animation show on start value. - The
PlayAnimationConfig.hideOnCompleteproperty lets you optionally override the animation hide on complete value. - The
PlayAnimationConfig.startFrameproperty lets you optionally set the animation frame to start on. - The
PlayAnimationConfig.timeScaleproperty lets you optionally set the animation time scale factor. AnimationState.delayCounteris a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animationSTARTevents fire. Fix #4426 (thanks @bdaenen)AnimationState.hasStartedis 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.showOnStartis a new boolean property that controls if the Game Object should havesetVisible(true)called on it when the animation starts.AnimationState.hideOnCompleteis a new boolean property that controls if the Game Object should havesetVisible(false)called on it when the animation completes.- The
AnimationState.chainmethod docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does! - The
AnimationState.setDelaymethod has been removed. It never actually worked and you can now perform the same thing by calling eitherplayAfterDelayor setting thedelayproperty in the play config. - The
AnimationState.getDelaymethod has been removed. You can now read thedelayproperty directly. - The
AnimationState.setRepeatmethod has been removed. You can achieve the same thing by setting therepeatproperty in the play config, or adjusting the publicrepeatCounterproperty if the animation has started. AnimationState.handleStartis a new internal private method that handles the animation start process.AnimationState.handleRepeatis a new internal private method that handles the animation repeat process.AnimationState.handleStopis a new internal private method that handles the animation stop process.AnimationState.handleCompleteis a new internal private method that handles the animation complete process.AnimationState.emitEventsis a new internal private method that emits animation events, cutting down on duplicate code.- The
AnimationState.restartmethod has a new optional boolean parameterresetRepeatswhich controls if you want to reset the repeat counter during the restart, or not. Animation.getTotalFramesis a new method that will return the total number of frames in the animation. You can access it viathis.anims.currentAnim.getTotalFramesfrom a Sprite.Animation.calculateDurationis a new method that calculates the duration, frameRate and msPerFrame for a given animation target.- The
BuildGameObjectAnimationfunction now uses thePlayAnimationConfigobject to set the values. Sprite.playReverseis a new method that allows you to play the given animation in reverse on the Sprite.Sprite.playAfterDelayis a new method that allows you to play the given animation on the Sprite after a delay.Sprite.stopis a new method that allows you to stop the current animation on the Sprite.AnimationManager.loadhas been removed as it's no longer required.AnimationManager.staggerPlayhas been fixed so you can now pass in negative stagger values.AnimationManager.staggerPlayhas a new optional boolean parameterstaggerFirst, which allows you to either include or exclude the first child in the stagger calculations.- The
Animation.completeAnimationmethod has been removed as it's no longer required. - The
Animation.loadmethod has been removed as it's no longer required. - The
Animation.setFramemethod has been removed as it's no longer required. - The
Animation.getFirstTickmethod has no longer needs theincludeDelayparameter, as it's handled byAnimationStatenow. - The
Animation.getFramesmethod has a new optional boolean parametersortFrameswhich will run a numeric sort on the frame names after constructing them, if a string-based frame is given. Types.Animations.Animationhas a new boolean propertysortFrames, which lets Phaser numerically sort the generated frames.AnimationState.timeScaleis a new public property that replaces the old private_timeScaleproperty.AnimationState.delayis a new public property that replaces the old private_delayproperty.AnimationState.repeatis a new public property that replaces the old private_repeatproperty.AnimationState.repeatDelayis a new public property that replaces the old private_repeatDelayproperty.AnimationState.yoyois a new public property that replaces the old private_yoyoproperty.AnimationState.inReverseis a new public property that replaces the old private_reverseproperty.AnimationState.startAnimationis a new public method that replaces the old private_startAnimationmethod.- The
AnimationState.getProgressmethod has been fixed so it will return correctly if the animation is playing in reverse. - The
AnimationState.globalRemovemethod will now always be called when an animation is removed from the global Animation Manager, not just once. - The
AnimationState.getRepeatmethod has now been removed. You can get the value from therepeatproperty. - The
AnimationState.setRepeatDelaymethod has now been removed. You can set the value using therepeatDelayconfig property, or changing it at run-time. AnimationState.completeis a new method that handles the completion in animation playback.- The
AnimationState.setTimeScalemethod has now been removed. You can set the value using thetimeScaleconfig property, or changing it at run-time. - The
AnimationState.getTimeScalemethod has now been removed. You can read the value using thetimeScaleproperty. - The
AnimationState.getTotalFramesmethod has been fixed and won't error if called when no animation is loaded. - The
AnimationState.setYoyomethod has now been removed. You can set the value using theyoyoconfig property, or changing it at run-time. - The
AnimationState.getYoyomethod has now been removed. You can read the value using theyoyoproperty. - The
AnimationState.stopAfterRepeatmethod now has an optional parameterrepeatCount, 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.updateFramemethod has now been removed. Everything is handled bysetCurrentFrameinstead, which removes one extra step out of the update process. GenerateFrameNameswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswould 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.GenerateFrameNumberscan now accept thestartandendparameters in reverse order, meaning you can now do{ start: 10, end: 1 }to create the animation in reverse.GenerateFrameNamescan now accept thestartandendparameters 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.createDynamicLayermethod has been renamed tocreateLayer. - The
Tilemap.createStaticLayermethod has been removed. UsecreateLayerinstead. - The
Tilemap.createBlankDynamicLayermethod has been renamed tocreateBlankLayer. - The
Tilemap.convertLayerToStaticmethod has been removed as it is no longer required. - The
TilemapLayerWebGLRendererfunction 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.TilemapOrientationTypeis a new type def that holds the 4 types of map orientation now supported.- The
Tile.updatePixelXYmethod now updates the tile XY position based on map type. ParseTilesetswill now correctly handle non-consecutive tile IDs. It also now correctly sets themaxIdproperty, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)Tilemap.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.LayerData.orientationis a new property that holds the tilemap layers orientation constant.LayerData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.MapData.orientationis a new property that holds the tilemap layers orientation constant.MapData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.Tilemaps.Components.HexagonalWorldToTileYis a new function that converts a world Y coordinate to hexagonal tile Y coordinate.Tilemaps.Components.StaggeredWorldToTileYis a new function that converts a world Y coordinate to staggered tile Y coordinate.Tilemaps.Components.HexagonalWorldToTileXYis a new function that converts world coordinates to hexagonal tile coordinates.Tilemaps.Components.IsometricWorldToTileXYis a new function that converts world coordinates to isometric tile coordinates.Tilemaps.Components.StaggeredWorldToTileXYis a new function that converts world coordinates to staggered tile coordinates.Tilemaps.Components.HexagonalTileToWorldYis a new function that converts a hexagonal Y coordinate to a world coordinate.Tilemaps.Components.StaggeredTileToWorldYis a new function that converts a staggered Y coordinate to a world coordinate.Tilemaps.Components.HexagonalTileToWorldXYis a new function that converts hexagonal tile coordinates to world coordinates.Tilemaps.Components.IsometricTileToWorldXYis a new function that converts isometric tile coordinates to world coordinates.Tilemaps.Components.StaggeredTileToWorldXYis a new function that converts staggered tile coordinates to world coordinates.Tilemaps.Components.GetTileToWorldXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldXXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetCullTilesFunctionis a new function that returns the correct culling function to use.Tilemaps.Components.HexagonalCullTilesis a new function that culls tiles in a hexagonal map.Tilemaps.Components.StaggeredCullTilesis a new function that culls tiles in a staggered map.Tilemaps.Components.IsometricCullTilesis a new function that culls tiles in a isometric map.Tilemaps.Components.CullBoundsis a new function that calculates the cull bounds for an orthogonal map.Tilemaps.Components.HexagonalCullBoundsis a new function that calculates the cull bounds for a hexagonal map.Tilemaps.Components.StaggeredCullBoundsis a new function that calculates the cull bounds for a staggered map.Tilemaps.Components.RunCullis a new function that runs the culling process from the combined bounds and tilemap.Tilemap._convertis a new internal private hash of tilemap conversion functions used by the public API.- The
Tilemap._isStaticCallmethod 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
GetTilesWithinWorldXYcomponent 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.Meshis 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.Vertexis a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.Geom.Mesh.Faceis a new class that consists of references to the threeVertexinstances that construct a single Face in a Mesh and provides methods for manipulating them.Geom.Mesh.GenerateVertsis a new function that will return an array ofVertexandFaceobjects 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.GenerateGridVertsis a new function that will generate a series ofVertexobjects in a grid format, based on the givenGenerateGridConfigconfig 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.GenerateObjVertsis a new function that will generate a series ofVertexobjects 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.ParseObjis a new function that will parse a triangulated Wavefront OBJ file into model data into a format that theGenerateObjVertsfunction can consume.Geom.Mesh.ParseObjMaterialis 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.RotateFaceis a new function that will rotate a Face by a given amount, based on an optional center of rotation.Loader.OBJFileis 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
MeshFactorysignatures have changed toscene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first.indiciesis a new parameter that allows you to provide indexed vertex data to create the Mesh from, where theindiciesarray holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. Theindiciesarray is optional. If your data is not indexed, then simply passnullor an empty array for this parameter. - The
MeshGame 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.addVerticesis 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.addVerticesFromObjis a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the newOBJFilewith athis.load.objcall, 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.hideCCWis 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.modelPositionis a new Vector3 property that allows you to translate the position of all vertices in the Mesh.Mesh.modelRotationis a new Vector3 property that allows you to rotate all vertices in the Mesh.Mesh.modelScaleis a new Vector3 property that allows you to scale all vertices in the Mesh.Mesh.panXis a new function that will translate the view position of the Mesh on the x axis.Mesh.panYis a new function that will translate the view position of the Mesh on the y axis.Mesh.panZis a new function that will translate the view position of the Mesh on the z axis.Mesh.setPerspectiveis a new method that allows you to set a perspective projection matrix based on the given dimensions, fov, near and far values.Mesh.setOrthois a new method that allows you to set an orthographic projection matrix based on the given scale, near and far values.Mesh.clearis a new method that will destroy all Faces and Vertices and clear the Mesh.Mesh.depthSortis a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.Mesh.addVertexis a new method that allows you to add a new single Vertex into the Mesh.Mesh.addFaceis a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.Mesh.getFaceCountnew is a new method that will return the total number of Faces in the Mesh.Mesh.getVertexCountnew is a new method that will return the total number of Vertices in the Mesh.Mesh.getFacenew is a new method that will return a Face instance from the Mesh based on the given index.Mesh.getFaceAtnew 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.verticesis now an array ofGameObject.Vertexinstances, not a Float32Array.Mesh.facesis a new array ofGameObject.Faceinstances, which is populated during a call to methods likeaddVerticesoraddModel.Mesh.totalRenderedis a new property that holds the total number of Faces that were rendered in the previous frame.Mesh.setDebugis 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
BringToTopto 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
MeshGame Object now extends theSingleAlphacomponent 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 standardsetAlphamethods. 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
colorsparameter in the constructor, factory method andaddVerticesmethod. 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
alphasparameter in the constructor, factory method andaddVerticesmethod. If a number, instead of an array, it will be used as the alpha for all vertices created. Mesh.debugGraphicis a new property that holds the debug Graphics instance reference.Mesh.debugCallbackis a new property that holds the debug render callback.Mesh.renderDebugVertsis a new method that acts as the default render callback forsetDebugif none is provided.Mesh.preDestroyis a new method that will clean-up the Mesh arrays and debug references on destruction.Mesh.isDirtyis a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically inpreUpdateto avoid generating lots of math when nothing has changed.- The
Mesh.uvarray has been removed. All UV data is now bound in the Vertex instances. - The
Mesh.colorsarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.alphasarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.tintFillproperty is now abooleanand defaults tofalse.
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.refreshis now called when theGame.READYevent 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
inputMouseCapturehas been removed, as this is now split into 3 new config options: inputMousePreventDefaultDownis a new config option that allows you to controlpreventDefaultcalls specifically on mouse down events. Set it viainput.mouse.preventDefaultDownin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultUpis a new config option that allows you to controlpreventDefaultcalls specifically on mouse up events. Set it viainput.mouse.preventDefaultUpin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultMoveis a new config option that allows you to controlpreventDefaultcalls specifically on mouse move events. Set it viainput.mouse.preventDefaultMovein the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultWheelis a new config option that allows you to controlpreventDefaultcalls specifically on mouse wheel events. Set it viainput.mouse.preventDefaultWheelin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.- The
MouseManager.captureproperty has been removed, as this is now split into 3 new config options (see below) MouseManager.preventDefaultDownis a new boolean property, set via theinputMousePreventDefaultDownconfig option that allows you to toggle capture of mouse down events at runtime.MouseManager.preventDefaultUpis a new boolean property, set via theinputMousePreventDefaultUpconfig option that allows you to toggle capture of mouse up events at runtime.MouseManager.preventDefaultMoveis a new boolean property, set via theinputMousePreventDefaultMoveconfig option that allows you to toggle capture of mouse move events at runtime.MouseManager.preventDefaultWheelis a new boolean property, set via theinputMousePreventDefaultWheelconfig option that allows you to toggle capture of mouse wheel at runtime.- In the
MouseManagerthe 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
GamepadPluginwill now callrefreshPadsas 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 viathis.input.gamepad.pad1and 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._createdis 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.downwill 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
useHandCursorenabled, 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.shutdownmethod 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.processOverEventshas 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.tintTopLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTLwhich has now been removed.Tint.tintTopRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTRwhich has now been removed.Tint.tintBottomLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBLwhich has now been removed.Tint.tintBottomRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBRwhich has now been removed.- The property
Tint._isTintedhas been removed as it's no longer required. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they now read the color value asoutTint.bgrinstead ofoutTint.rgb. This allows the colors to remain in RGB order within the Tint component. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they no longer have a 3-way check on theoutTintEffectvalue. - The
Multi Pipeline,Bitmap Text,Render Texture,Text,TileSpriteandCameranow all read the tint values from the public properties instead of the private_tintTLetc ones. They also now set thetintEffectvalue directly from thetintFillproperty, removing another conditional check. - The function
GetColorFromValuehas been removed as it's no longer used internally. - The
Rope.tintFillproperty is now a boolean, not an integer, and can no longer take2as 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
getTintAppendFloatAlphaAndSwaphave been replaced withgetTintAppendFloatAlphainstead. - As a result of the change to the shader, the Multi Pipeline now uses the
WebGLRenderer.whiteTextureandtintEffectmode 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.whiteTextureis 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
TextureManagernow generates a new texture with the key__WHITEdurings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines. Config.images.whiteis 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
Bodyclass has a new boolean propertypushable(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.setPushableis a new chainable method that allows you to set thepushablestate of a Body.Arcade.Components.Pushableis 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.disableUpdateis a new method that will prevent the Arcade Physics Worldupdatemethod 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.enableUpdateis 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.customUpdateis a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. Iftruethe World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)Physics.Arcade.Body.setCollideWorldBoundsnow has a new optional parameteronWorldBoundswhich allows you to enable the Body'sonWorldBoundsproperty in the same call (thanks @samme)ArcadePhysics.Body.setMaxVelocityXis a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)ArcadePhysics.Body.setMaxVelocityYis a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)- The
PhysicsGroupconfig now has two new optional propertiesmaxVelocityXandmaxVelocityYwhich allows you to set the maximum velocity on bodies added to the Group (thanks @samme) - The
Arcade.Body.resetFlagsmethod has a new optional boolean parameterclear. If set, it clears thewasTouchingflags on the Body. This happens automatically whenBody.resetis called. Previous to this, the flags were not reset until the next physics step (thanks @samme) Physics.Arcade.ProcessXis a new set of functions, called by theSeparateXfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Physics.Arcade.ProcessYis a new set of functions, called by theSeparateYfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Arcade.Body.centervalues 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.
AtlasJSONFileno longer stores the JSON in the JSON Cache once the texture has been created.AtlasXMLFileno longer stores the XML in the XML Cache once the texture has been created.UnityAtlasFileno longer stores the Text in the Text Cache once the texture has been created.BitmapFontFileno longer stores the XML in the XML Cache once the texture has been created.- You can now use
TextureManager.removeto 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#RESIZEevent no longer sends theresolutionas a parameter. - The
BaseCamera.resolutionproperty has been removed. - The internal private
BaseCamera._cx,_cy,_cwand_chproperties has been removed, usex,y,widthandheightinstead. - The
BaseCamera.preRendermethod no longer receives or uses theresolutionparameter. - The
Camera.preRendermethod no longer receives or uses theresolutionparameter. - The
CameraManager.onResizemethod no longer receives or uses theresolutionparameter. - The
Core.Config.resolutionproperty has been removed. - The
TextStyle.resolutionproperty 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
CanvasRendererno longer reads or uses the Game Config resolution property. - The
PipelineManager.resizemethod along withWebGLPipeline.resizeand anything else that extends them no longer receives or uses theresolutionparameter. - The
WebGLRenderer.resizeandonResizemethods no longer receives or uses theresolutionparameter. - The
ScaleManager.resolutionproperty 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.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Intersects.GetLineToPointsis 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.GetRaysFromPointToPolygonis 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.Translateis a new function that allows you to translate all the points of a polygon by the given values.Geom.Polygon.Simplifyis 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.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.getTweensOfhas a new parameterincludePending. 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.hasBootedis 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 theWebGLRenderer.addPipelinemethod, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)- The WebGL Renderer will now add the pipelines during the
bootmethod, instead ofinit. - You can now use
this.rendererfrom within a Scene, as it's now a Scene-level property and part of the Injection Map. Clock.addEventcan now take an existingTimerEventobject, as well as a config object. If aTimerEventis 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.removeEventis a new method that allows you to remove aTimerEvent, or an array of them, from all internal lists of the current Clock.Group.getMatchingis a new method that will return any members of the Group that match the given criteria, such asgetMatching('visible', true)(thanks @atursams)Utils.Array.SortByDigitsis 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 callingGroup.createMultipleorGroup.createFromConfig, can now accept the following new properties:setOrigin: { x, y, stepX, stepY }which are applied to the items created by the Group.Transform.copyPositionis a new method that will copy the position from the given object to the Game Object (thanks @samme)- The
Text.MeasureTextfunction, 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 newactualBoundingBoxAscentfunctions 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.GetCalcMatrixis 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,StarandTriangle. This dramatically reduces the amount of duplicate code across the API.Utils.Array.Matrix.Translateis a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.Vertor3.addScaleis 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
easeParamsin the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh) BitmapMask.createMaskis 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.clearMaskwill 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.Quaternionnow has a new propertyonChangeCallbackwhich, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.- The
Quaternion.setmethod has a new optional boolean parameterupdate(defaults totrue), which will call theonChangeCallbackif set. Quaternion.setFromEuleris a new method that will set the quaternion from the givenEulerobject, optionally calling theonChangeCallbackin the process.Quaternion.setFromRotationMatrixis a new method that will set the rotation of the quaternion from the given Matrix4.Vector3.setFromMatrixPositionis a new method that will set the components of the Vector3 based on the position of the given Matrix4.Vector3.setFromMatrixColumnis a new method that will set the components of the Vector3 based on the specified Matrix4 column.Vector3.fromArrayis a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.Vector3.minis a new method that will set the components of the Vector3 based on theMain.minbetween it and the given Vector3.Vector3.maxis a new method that will set the components of the Vector3 based on theMain.maxbetween it and the given Vector3.Vector3.addVectorsis a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.Vector3.addScalaris a new method that will multiply the components of the Vector3 by the scale value given.Vector3.applyMatrix3is a new method that will take a Matrix3 and apply it to the Vector3.Vector3.applyMatrix4is a new method that will take a Matrix4 and apply it to the Vector3.Vector3.projectViewMatrixis a new method that multiplies the Vector3 by the given view and projection matrices.Vector3.unprojectViewMatrixis a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.Matrix4.setValuesis a new method that allows you to set all of the matrix components individually. Most internal methods now use this.Matrix.multiplyToMat4is a new method that multiplies a Matrix4 by the givensrcMatrix4 and stores the results in theoutMatrix4.Matrix4.fromRotationXYTranslationis a new method that takes the rotation and position vectors and builds this Matrix4 from them.Matrix4.getMaxScaleOnAxisis a new method that will return the maximum axis scale from the Matrix4.Matrix4.lookAtRHis a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.Matrix4.transformis a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.Matrix4.multiplyMatricesis a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.Matrix4.premultiplyis a new method that takes a Matrix4 and multiplies it by the current Matrix4.Matrix4.getInverseis a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.CameraManager.getVisibleChildrenis a new method that is called internally by theCameraManager.rendermethod. It filters the DisplayList, so that Game Objects that pass thewillRendertest 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.setDampingis a new method that allows you to set theuseDampingproperty of a Body in a chainable way. Fix #5352 (thanks @juanitogan)- The
GameObjects.Graphics.fillGradientStylemethod 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.PipelineConfigis a new configuration object that you can set in the Game Config under thepipelineproperty. 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 thepipelineobject, or set it under therendersub-config.Utils.Object.DeepCopyis 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.Earcutand is fully documented. Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself. - The constant
Phaser.Renderer.WebGL.BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.FLOATvalue has been removed as it wasn't used internally. Pointer.downTimenow 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.upTimenow 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.getDurationmethod now uses the new PointerdownTimeandupTimevalues, 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
BaseShaderdefault vertex shader now includes theoutTexCoordvec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok) - When using the
GameObjectCreatorforContainersyou can now specify thechildrenproperty in the configuration object. Textures.Parsers.JSONHashwill now perform ahasOwnPropertycheck when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes fromJSON.parse. Fix #4768 (thanks @RollinSafary)- The
Camera3DPlugin 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.seekwill 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
inputWindowEventsis set in the Game Config, then theMouseManagerwill now listen for the events onwindow.topinstead of justwindow, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in atry/catchblock, as not all sites allow access towindow.top(specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow) MouseManager.isTopis a new boolean read-only property that flags if the mouse event listeners were attached towindow.top(true), or justwindow(false). By default Phaser will attemptwindow.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back towindowin those cases and set this property to false (thanks BunBunBun)Types.GameObjects.Text.GetTextSizeObjectis a new type def for the GetTextSize function results.Utils.Array.StableSorthas 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. Theinplacefunction has been removed, just callStableSort(array)directly now. All classes that usedStableSort.inplacehave 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.setOriginwill now callupdateDisplayOriginon the items array, otherwise the effects can't be seen when rendering.- You can now set the
ArcadeWorld.fixedStepproperty via theArcadeWorldConfigobject (thanks @samme) Utils.Array.NumerArraycan now accept thestartandendparameters in reverse order, i.e.10, 1will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.DataManager.Events.DESTROYis a new event that the Data Manager will listen for from its parent and then call its owndestroymethod when received.- The
Quaternionclass constructor will now default the values to0,0,0,1if they're not provided, making it an identity quaternion, rather than the0,0,0,0it was before. - You can now set the
ParticleEmitter.reservevalue via the emitter configuration object (thanks @vforsh) - Setting the
pixelArtconfig option will now setantialiasGLtofalse, as well asantialias. Fix #5309 (thanks @Vegita2) - The
Shapeclass now includes theComputedSizecomponent properties and methods directly in the class, rather than applying as a mixin.setSizeis now flagged as beingprivate, 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.maxParallelDownloadsvalue is now set to 6 if running on Android, or 32 on any other OS. This avoidsnet::ERR_FAILEDissues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary) - When running an Arcade Physics
overlaptest against aStaticBody, it will no longer set theblockedstates 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
LineGame 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
Quaternionclass now has 4 new private properties:_x,_y,_zand_wand 4 new getters and setters for the public versions. It also now passes most methods viasetto allow for the onChange callback to be invoked. This does not change the public-facing API. Groupnow extendsEventEmitter, allowing you to emit custom events from within a Group.Device.Audio.wavnow usesaudio/wavas thecanPlayTypecheck string, instead ofaudio/wav; codecs="1", which should allow iOS13 to play wav files again.- In the
Loader.FileTypes.TextFileconfig you can now override the type and cache destination for the file. Loader.MultiFilewill 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.tintvalue is now0xffffff(previously, it was0xffffffff) to allow particle tints to work in the correct RGB order including alpha (thanks @vforsh) SceneManager.startwill now reset theSceneSystems.sceneUpdatereference toNOOP. This gets set back to the Scene update method again duringbootScene(if it has one) and stops errors with external plugins and multi-part files that may triggerupdatebeforecreatehas been called. Fix #4629 (thanks @Osmose)Phaser.Scene.rendereris a new property available in every Phaser.Scene that gives you a reference to the renderer, either Canvas or WebGL.- The
CanvasRenderer._tempMatrix1,_tempMatrtix2,_tempMatrix3and_tempMatrix4properties 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 globalGetCalcMatrixfunction instead.
Bug Fixes
RenderTexture.resize(which is called fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.RenderTexture.fillwould 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
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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
ProcessQueuewas emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar) - The
GridAlignaction didn't work if only theheightparameter was set. Fix #5019 (thanks @halilcakar) - The
Color.HSVToRGBfunction has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX) - Previously, the
easeParamsarray within a Tweenspropsobject, 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.setRenderToTextureitszoomandrotationvalues would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok) GameObjects.Shape.Gridwould render a white fill even if you passedundefinedas the fill color in the constructor. It now doesn't render cells if no fill color is given.- The
onMouseevents in the Input Manager didn't reset theactivePointerproperty 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
GetScreenOrientationfunction will now check forwindow.orientationfirst, 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 emitorientationchangeevents correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu) Time.Clock.addEventcan now take an instance of aTimerEventas its parameter. Fix #5294 (thanks @samme @EmilSV)GameConfig.audionow defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)- The
Loader.pathwas 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.getMatchingwould always return an empty array. It now returns matching children (thanks @samme)- The
ParticleManagerWebGLRenderernow 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
ParticleManagerCanvasRenderernow calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also usessetToContextinternally. 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
GraphicsWebGL Renderer will now default topathOpen = true. This fixes issues under WebGL where, for example, adding an arc and callingstrokePath, without first callingbeginPathwill no longer cause rendering artefacts when WebGL tries to close the path with a single tri. Graphics.strokeRoundedRectnow issuesmoveTocommands 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
snapshotin WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in theWebGLSnapshotfunction. Fix #4956 (thanks @gammafp @telinc1) - You can now draw a
Groupto aRenderTexture. Previously, it failed to pass the camera across, resulting in none of the Group children being drawn. Fix #5330 (thanks @somnolik) Particles.EmitterOp.setMethodswill now reset bothonEmitandonUpdateto 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.EmitterOpnow cleanly separates between the different types of property configuration options.start | endwill now ease between the two values,min | maxwill pick a random value between them andrandom: []will pick a random element. They no longer get mixed together. Fix #3608 (thanks @samme)- When setting both
transparent: trueandbackgroundColorin 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.MoveTofunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.DOM.GetInnerHeightfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Bobclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsManagerclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsPluginclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Particles.EmitterOpclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.GetTextSizefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.MeasureTextfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.TextStylefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Input.CreatePixelPerfectHandlerfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapCircfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapRectfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Tilemapnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Componentsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.MatterGameObjectclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.PointerConstraintclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetPhysicsPluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetScenePluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Structs.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Tilemaps.Parsers.Tiledfunction has now been exposed on the Phaser namespace (thanks @samme) - Every single
Tilemap.Componentfunction 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:
TextureTintPipelineis now called theMultiPipeline.TextureTintStripPipelineis now called theRopePipeline.ForwardDiffuseLightPipelineis now called theLightPipeline.
To match the new pipeline names, the shader source code has also been renamed.
ForwardDiffuse.fragis now calledLight.frag.TextureTint.fragis now calledMulti.frag.TextureTint.vertis now calledMulti.vert.
Other pipeline changes are as follows:
Types.Renderer.WebGL.WebGLPipelineConfigis a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.Types.Renderer.WebGL.WebGLPipelineAttributesConfigis 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
rendererproperty automatically, so it's no longer required in the config. - All pipelines will now work out the
glproperty automatically, so it's no longer required in the config. - All pipelines will now extract the
nameproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexCapacityproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexSizeproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexDataproperty from the config, allowing you to set it externally. - All pipelines will now extract the
attributesproperty from the config, allowing you to set it externally. - All pipelines will now extract the
topologyproperty from the config, allowing you to set it externally. - The
WebGLPipeline.shouldFlushmethod now accepts an optional parameteramount. If given, it will returntrueif 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
RopePipelinenow extendsMultiPipelineand 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.set1fwill set a 1f uniform based on the given name.WebGLPipeline.set2fwill set a 2f uniform based on the given name.WebGLPipeline.set3fwill set a 3f uniform based on the given name.WebGLPipeline.set4fwill set a 4f uniform based on the given name.WebGLPipeline.set1fvwill set a 1fv uniform based on the given name.WebGLPipeline.set2fvwill set a 2fv uniform based on the given name.WebGLPipeline.set3fvwill set a 3fv uniform based on the given name.WebGLPipeline.set4fvwill set a 4fv uniform based on the given name.WebGLPipeline.set1ivwill set a 1iv uniform based on the given name.WebGLPipeline.set2ivwill set a 2iv uniform based on the given name.WebGLPipeline.set3ivwill set a 3iv uniform based on the given name.WebGLPipeline.set4ivwill set a 4iv uniform based on the given name.WebGLPipeline.set1iwill set a 1i uniform based on the given name.WebGLPipeline.set2iwill set a 2i uniform based on the given name.WebGLPipeline.set3iwill set a 3i uniform based on the given name.WebGLPipeline.set4iwill set a 4i uniform based on the given name.WebGLPipeline.setMatrix2fvwill set a matrix 2fv uniform based on the given name.WebGLPipeline.setMatrix3fvwill set a matrix 3fv uniform based on the given name.WebGLPipeline.setMatrix4fvwill 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.setFloat1has been removed. Please useset1finstead.WebGLPipeline.setFloat2has been removed. Please useset2finstead.WebGLPipeline.setFloat3has been removed. Please useset3finstead.WebGLPipeline.setFloat4has been removed. Please useset4finstead.WebGLPipeline.setFloat1vhas been removed. Please useset1fvinstead.WebGLPipeline.setFloat2vhas been removed. Please useset2fvinstead.WebGLPipeline.setFloat3vhas been removed. Please useset3fvinstead.WebGLPipeline.setFloat4vhas been removed. Please useset4fvinstead.WebGLPipeline.setInt1has been removed. Please useset1iinstead.WebGLPipeline.setInt2has been removed. Please useset2iinstead.WebGLPipeline.setInt3has been removed. Please useset3iinstead.WebGLPipeline.setInt4has been removed. Please useset4iinstead.WebGLPipeline.setMatrix1has been removed. Please usesetMatrix2fvinstead.WebGLPipeline.setMatrix2has been removed. Please usesetMatrix3fvinstead.WebGLPipeline.setMatrix3has been removed. Please usesetMatrix4fvinstead.
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.pipelinesis no longer a plain object containing pipeline instances. It's now an instance of thePipelineManagerclass. This instance is created during the init and boot phase of the renderer.- The
WebGLRenderer.currentPipelineproperty no longer exists, instead usePipelineManager.current. - The
WebGLRenderer.previousPipelineproperty no longer exists, instead usePipelineManager.previous. - The
WebGLRenderer.hasPipelinemethod no longer exists, instead usePipelineManager.has. - The
WebGLRenderer.getPipelinemethod no longer exists, instead usePipelineManager.get. - The
WebGLRenderer.removePipelinemethod no longer exists, instead usePipelineManager.remove. - The
WebGLRenderer.addPipelinemethod no longer exists, instead usePipelineManager.add. - The
WebGLRenderer.setPipelinemethod no longer exists, instead usePipelineManager.set. - The
WebGLRenderer.rebindPipelinemethod no longer exists, instead usePipelineManager.rebind. - The
WebGLRenderer.clearPipelinemethod no longer exists, instead usePipelineManager.clear.
The Pipeline Manager also offers the following new features:
- The
PipelineManager.resizemethod automatically handles resize events across all pipelines. - The
PipelineManager.preRendermethod calls the pre-render method of all pipelines. - The
PipelineManager.rendermethod calls the render method of all pipelines. - The
PipelineManager.postRendermethod calls the post-render method of all pipelines. - The
PipelineManager.setMultimethod automatically binds the Multi Texture Pipeline, Phaser's default. - The
PipelineManager.clearmethod will clear the pipeline, store it inpreviousand free the renderer. - The
PipelineManager.rebindmethod will reset the rendering context and restore thepreviouspipeline, if set.
New constants have been created to help you reference a pipeline without needing to use strings:
Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINEfor the Bitmap Mask Pipeline.Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINEfor the Light 2D Pipeline.Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINEfor the Single Pipeline.Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINEfor the Multi Pipeline.Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINEfor 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture that was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLPipeline.forceZerois a new property that informs Game Objects if the pipeline requires a zero bound texture unit.WebGLPipeline.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLRenderer.unbindTexturesis a new method that will activate and then null bind all WebGL textures.Renderer.WebGL.Utils.parseFragmentShaderMaxTexturesis 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis a new method that will look-up and return a normal map for the given object.
Lights
Light.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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.MVPis a new namespace under which the Model View Projection functions now live.projIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectIdentityprojPerspis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectPerspectivemodelRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateXmodelRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateYmodelRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateZviewLoadis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoadviewRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateXviewRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateYviewRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateZviewScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewScaleviewTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewTranslatemodelIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.IdentitymodelScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ScalemodelTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.TranslateviewIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewIdentityviewLoad2Dis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoad2DprojOrthois now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectOrthoPhaser.Renderer.WebGL.MVP.SetIdentityis a new function the others use, to save on space.
BitmapText - New Features, Updates and API Changes
BitmapText.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycoordinates. The character data includes the code, position, dimensions, and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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
setMaxWidthonDynamicBitmapText, 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_SCENEis 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_SCENEis 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_SCENEis 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_SCENEis 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.addedToSceneis 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.removedFromSceneis 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 theremovedFromScenemethod now. - The
Containerwill 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.eventsis a new property that references the Scene's Event Emitter. This is now used internally.DisplayList.addChildCallbackis a new method that overrides the List callback and fires the new ADDED events.DisplayList.removeChildCallbackis a new method that overrides the List callback and fires the new REMOVED events.GameObjectCreator.eventsis a new property that references the Scene's Event Emitter. This is now used internally.GameObjectFactory.eventsis a new property that references the Scene's Event Emitter. This is now used internally.ProcessQueue.checkQueueis a new boolean property that will make sure only unique objects are added to the Process Queue.- The
Update Listnow uses the newcheckQueueproperty to ensure no duplicate objects are on the active list. DOMElementFactory,ExternFactory,ParticleManagerFactor,RopeFactoryandSpriteFactoryall no longer add the objects to the Update List, this is now handled by the ADDED events instead.Sprite,Rope,ParticleEmitterManager,ExternandDOMElementnow all override theaddedToSceneandremovedFromScenecallbacks 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.
SpineContaineris a new Game Object available viathis.add.spineContainerto 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.runtimeswhich will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo intoplugins/spine/in order for this to work and then runnpm 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-zeroerror 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.setAnimationmethod will now use thetrackIndexparameter ifignoreIfPlayingis set and run the check against this track index. Fix #4842 (thanks @vinerz) - The
SpineFilewill 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
destroymethod 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.gameDestroyis a new method that is called if the Game instance emits adestroyevent. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.SpineFilewill 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)SpineFilenow 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
Animationclass no longer extendsEventEmitter, 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_KEYevents have been removed. Instead, please use the new events which all carry theframeKeyparameter, which can be used to handle frame specific events. The only exception to this isANIMATION_COMPLETE_KEY, which is a key specific version of the completion event. ANIMATION_UPDATE_EVENTis a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.ANIMATION_STOP_EVENTis a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of thestopmethods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)- The Game Object
Component.Animationcomponent has been renamed toAnimationStateand has moved namespace. It's now inPhaser.Animationsinstead ofGameObjects.Componentsto help differentiate it from theAnimationclass when browsing the documentation. - The
play,playReverse,playAfterDelay,playAfterRepeatandchainSprite and Animation Component methods can now all take aPhaser.Types.Animations.PlayAnimationConfigconfiguration object, as well as a string, as thekeyparameter. 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.createis 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.generateFrameNumbersis 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.generateFrameNamesis 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,playAfterDelayandplayAfterRepeatwill 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.skipMissedFramesis 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.addMixis 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.getMixis a new method that will return the mix duration between the two given animations.AnimationManager.removeMixis a new method that will remove the mixture between either two animations, or all mixtures for the given animation.AnimationState.removeis a new method that will remove a locally stored Animation instance from a Sprite.AnimationState.getis a new method that will return a locally stored Animation instance from the Sprite.AnimationState.existsis a new method that will check if a locally stored Animation exists on the Sprite.- The internal
AnimationState.removemethod has been renamed toglobalRemove. AnimationState.textureManageris a new property that references the global Texture Manager.AnimationState.animsis a new property that contains locally created Animations in a Custom Map.AnimationState.playandSprite.playno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.AnimationState.playReverseandSprite.playReverseno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.- The
AnimationState.delayedPlaymethod has been renamed toplayAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration. - The
AnimationState.stopOnRepeatmethod has been renamed tostopAfterRepeat - The
AnimationState.getCurrentKeymethod has been renamed togetName. AnimationState.getFrameNameis a new method that will return the key of the current Animation Frame, if an animation has been loaded.AnimationState.playAfterDelayandSprite.playAfterDelayare new methods that will play the given animation after the delay in ms expires.AnimationState.playAfterRepeatandSprite.playAfterRepeatare 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.chainmethod is now available on the Sprite class. - The
AnimationState.stopAfterDelaymethod is now available on the Sprite class. - The
AnimationState.stopAfterRepeatmethod is now available on the Sprite class. - The
AnimationState.stopOnFramemethod is now available on the Sprite class. AnimationManager.createFromAsepriteis 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.AnimationStatenow 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 optionalPlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.- The
PlayAnimationConfig.frameRateproperty lets you optionally override the animation frame rate. - The
PlayAnimationConfig.durationproperty lets you optionally override the animation duration. - The
PlayAnimationConfig.delayproperty lets you optionally override the animation delay. - The
PlayAnimationConfig.repeatproperty lets you optionally override the animation repeat counter. - The
PlayAnimationConfig.repeatDelayproperty lets you optionally override the animation repeat delay value. - The
PlayAnimationConfig.yoyoproperty lets you optionally override the animation yoyo boolean. - The
PlayAnimationConfig.showOnStartproperty lets you optionally override the animation show on start value. - The
PlayAnimationConfig.hideOnCompleteproperty lets you optionally override the animation hide on complete value. - The
PlayAnimationConfig.startFrameproperty lets you optionally set the animation frame to start on. - The
PlayAnimationConfig.timeScaleproperty lets you optionally set the animation time scale factor. AnimationState.delayCounteris a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animationSTARTevents fire. Fix #4426 (thanks @bdaenen)AnimationState.hasStartedis 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.showOnStartis a new boolean property that controls if the Game Object should havesetVisible(true)called on it when the animation starts.AnimationState.hideOnCompleteis a new boolean property that controls if the Game Object should havesetVisible(false)called on it when the animation completes.- The
AnimationState.chainmethod docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does! - The
AnimationState.setDelaymethod has been removed. It never actually worked and you can now perform the same thing by calling eitherplayAfterDelayor setting thedelayproperty in the play config. - The
AnimationState.getDelaymethod has been removed. You can now read thedelayproperty directly. - The
AnimationState.setRepeatmethod has been removed. You can achieve the same thing by setting therepeatproperty in the play config, or adjusting the publicrepeatCounterproperty if the animation has started. AnimationState.handleStartis a new internal private method that handles the animation start process.AnimationState.handleRepeatis a new internal private method that handles the animation repeat process.AnimationState.handleStopis a new internal private method that handles the animation stop process.AnimationState.handleCompleteis a new internal private method that handles the animation complete process.AnimationState.emitEventsis a new internal private method that emits animation events, cutting down on duplicate code.- The
AnimationState.restartmethod has a new optional boolean parameterresetRepeatswhich controls if you want to reset the repeat counter during the restart, or not. Animation.getTotalFramesis a new method that will return the total number of frames in the animation. You can access it viathis.anims.currentAnim.getTotalFramesfrom a Sprite.Animation.calculateDurationis a new method that calculates the duration, frameRate and msPerFrame for a given animation target.- The
BuildGameObjectAnimationfunction now uses thePlayAnimationConfigobject to set the values. Sprite.playReverseis a new method that allows you to play the given animation in reverse on the Sprite.Sprite.playAfterDelayis a new method that allows you to play the given animation on the Sprite after a delay.Sprite.stopis a new method that allows you to stop the current animation on the Sprite.AnimationManager.loadhas been removed as it's no longer required.AnimationManager.staggerPlayhas been fixed so you can now pass in negative stagger values.AnimationManager.staggerPlayhas a new optional boolean parameterstaggerFirst, which allows you to either include or exclude the first child in the stagger calculations.- The
Animation.completeAnimationmethod has been removed as it's no longer required. - The
Animation.loadmethod has been removed as it's no longer required. - The
Animation.setFramemethod has been removed as it's no longer required. - The
Animation.getFirstTickmethod has no longer needs theincludeDelayparameter, as it's handled byAnimationStatenow. - The
Animation.getFramesmethod has a new optional boolean parametersortFrameswhich will run a numeric sort on the frame names after constructing them, if a string-based frame is given. Types.Animations.Animationhas a new boolean propertysortFrames, which lets Phaser numerically sort the generated frames.AnimationState.timeScaleis a new public property that replaces the old private_timeScaleproperty.AnimationState.delayis a new public property that replaces the old private_delayproperty.AnimationState.repeatis a new public property that replaces the old private_repeatproperty.AnimationState.repeatDelayis a new public property that replaces the old private_repeatDelayproperty.AnimationState.yoyois a new public property that replaces the old private_yoyoproperty.AnimationState.inReverseis a new public property that replaces the old private_reverseproperty.AnimationState.startAnimationis a new public method that replaces the old private_startAnimationmethod.- The
AnimationState.getProgressmethod has been fixed so it will return correctly if the animation is playing in reverse. - The
AnimationState.globalRemovemethod will now always be called when an animation is removed from the global Animation Manager, not just once. - The
AnimationState.getRepeatmethod has now been removed. You can get the value from therepeatproperty. - The
AnimationState.setRepeatDelaymethod has now been removed. You can set the value using therepeatDelayconfig property, or changing it at run-time. AnimationState.completeis a new method that handles the completion in animation playback.- The
AnimationState.setTimeScalemethod has now been removed. You can set the value using thetimeScaleconfig property, or changing it at run-time. - The
AnimationState.getTimeScalemethod has now been removed. You can read the value using thetimeScaleproperty. - The
AnimationState.getTotalFramesmethod has been fixed and won't error if called when no animation is loaded. - The
AnimationState.setYoyomethod has now been removed. You can set the value using theyoyoconfig property, or changing it at run-time. - The
AnimationState.getYoyomethod has now been removed. You can read the value using theyoyoproperty. - The
AnimationState.stopAfterRepeatmethod now has an optional parameterrepeatCount, 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.updateFramemethod has now been removed. Everything is handled bysetCurrentFrameinstead, which removes one extra step out of the update process. GenerateFrameNameswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswould 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.GenerateFrameNumberscan now accept thestartandendparameters in reverse order, meaning you can now do{ start: 10, end: 1 }to create the animation in reverse.GenerateFrameNamescan now accept thestartandendparameters 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.createDynamicLayermethod has been renamed tocreateLayer. - The
Tilemap.createStaticLayermethod has been removed. UsecreateLayerinstead. - The
Tilemap.createBlankDynamicLayermethod has been renamed tocreateBlankLayer. - The
Tilemap.convertLayerToStaticmethod has been removed as it is no longer required. - The
TilemapLayerWebGLRendererfunction 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.TilemapOrientationTypeis a new type def that holds the 4 types of map orientation now supported.- The
Tile.updatePixelXYmethod now updates the tile XY position based on map type. ParseTilesetswill now correctly handle non-consecutive tile IDs. It also now correctly sets themaxIdproperty, fixing a bug where tiles wouldn't render if from IDs outside the expected range. Fix #4367 (thanks @jackfreak)Tilemap.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.LayerData.orientationis a new property that holds the tilemap layers orientation constant.LayerData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.MapData.orientationis a new property that holds the tilemap layers orientation constant.MapData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.Tilemaps.Components.HexagonalWorldToTileYis a new function that converts a world Y coordinate to hexagonal tile Y coordinate.Tilemaps.Components.StaggeredWorldToTileYis a new function that converts a world Y coordinate to staggered tile Y coordinate.Tilemaps.Components.HexagonalWorldToTileXYis a new function that converts world coordinates to hexagonal tile coordinates.Tilemaps.Components.IsometricWorldToTileXYis a new function that converts world coordinates to isometric tile coordinates.Tilemaps.Components.StaggeredWorldToTileXYis a new function that converts world coordinates to staggered tile coordinates.Tilemaps.Components.HexagonalTileToWorldYis a new function that converts a hexagonal Y coordinate to a world coordinate.Tilemaps.Components.StaggeredTileToWorldYis a new function that converts a staggered Y coordinate to a world coordinate.Tilemaps.Components.HexagonalTileToWorldXYis a new function that converts hexagonal tile coordinates to world coordinates.Tilemaps.Components.IsometricTileToWorldXYis a new function that converts isometric tile coordinates to world coordinates.Tilemaps.Components.StaggeredTileToWorldXYis a new function that converts staggered tile coordinates to world coordinates.Tilemaps.Components.GetTileToWorldXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldXXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetCullTilesFunctionis a new function that returns the correct culling function to use.Tilemaps.Components.HexagonalCullTilesis a new function that culls tiles in a hexagonal map.Tilemaps.Components.StaggeredCullTilesis a new function that culls tiles in a staggered map.Tilemaps.Components.IsometricCullTilesis a new function that culls tiles in a isometric map.Tilemaps.Components.CullBoundsis a new function that calculates the cull bounds for an orthogonal map.Tilemaps.Components.HexagonalCullBoundsis a new function that calculates the cull bounds for a hexagonal map.Tilemaps.Components.StaggeredCullBoundsis a new function that calculates the cull bounds for a staggered map.Tilemaps.Components.RunCullis a new function that runs the culling process from the combined bounds and tilemap.Tilemap._convertis a new internal private hash of tilemap conversion functions used by the public API.- The
Tilemap._isStaticCallmethod 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.Meshis 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.Vertexis a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.Geom.Mesh.Faceis a new class that consists of references to the threeVertexinstances that construct a single Face in a Mesh and provides methods for manipulating them.Geom.Mesh.GenerateVertsis a new function that will return an array ofVertexandFaceobjects 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.GenerateGridVertsis a new function that will generate a series ofVertexobjects in a grid format, based on the givenGenerateGridConfigconfig 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.GenerateObjVertsis a new function that will generate a series ofVertexobjects 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.ParseObjis a new function that will parse a triangulated Wavefront OBJ file into model data into a format that theGenerateObjVertsfunction can consume.Geom.Mesh.ParseObjMaterialis 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.RotateFaceis a new function that will rotate a Face by a given amount, based on an optional center of rotation.Loader.OBJFileis 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
MeshFactorysignatures have changed toscene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first.indiciesis a new parameter that allows you to provide indexed vertex data to create the Mesh from, where theindiciesarray holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. Theindiciesarray is optional. If your data is not indexed, then simply passnullor an empty array for this parameter. - The
MeshGame 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.addVerticesis 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.addVerticesFromObjis a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the newOBJFilewith athis.load.objcall, 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.hideCCWis 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.modelPositionis a new Vector3 property that allows you to translate the position of all vertices in the Mesh.Mesh.modelRotationis a new Vector3 property that allows you to rotate all vertices in the Mesh.Mesh.modelScaleis a new Vector3 property that allows you to scale all vertices in the Mesh.Mesh.panXis a new function that will translate the view position of the Mesh on the x axis.Mesh.panYis a new function that will translate the view position of the Mesh on the y axis.Mesh.panZis a new function that will translate the view position of the Mesh on the z axis.Mesh.updateProjectionMatrixis a new method that allows you to set the projection matrix based on the given size, fov, near and far values.Mesh.clearis a new method that will destroy all Faces and Vertices and clear the Mesh.Mesh.depthSortis a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.Mesh.addVertexis a new method that allows you to add a new single Vertex into the Mesh.Mesh.addFaceis a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.Mesh.getFaceCountnew is a new method that will return the total number of Faces in the Mesh.Mesh.getVertexCountnew is a new method that will return the total number of Vertices in the Mesh.Mesh.getFacenew is a new method that will return a Face instance from the Mesh based on the given index.Mesh.getFaceAtnew 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.verticesis now an array ofGameObject.Vertexinstances, not a Float32Array.Mesh.facesis a new array ofGameObject.Faceinstances, which is populated during a call to methods likeaddVerticesoraddModel.Mesh.totalRenderedis a new property that holds the total number of Faces that were rendered in the previous frame.Mesh.setDebugis 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
BringToTopto 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
MeshGame Object now extends theSingleAlphacomponent 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 standardsetAlphamethods. 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
colorsparameter in the constructor, factory method andaddVerticesmethod. 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
alphasparameter in the constructor, factory method andaddVerticesmethod. If a number, instead of an array, it will be used as the alpha for all vertices created. Mesh.debugGraphicis a new property that holds the debug Graphics instance reference.Mesh.debugCallbackis a new property that holds the debug render callback.Mesh.renderDebugVertsis a new method that acts as the default render callback forsetDebugif none is provided.Mesh.preDestroyis a new method that will clean-up the Mesh arrays and debug references on destruction.Mesh.isDirtyis a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically inpreUpdateto avoid generating lots of math when nothing has changed.- The
Mesh.uvarray has been removed. All UV data is now bound in the Vertex instances. - The
Mesh.colorsarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.alphasarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.tintFillproperty is now abooleanand defaults tofalse.
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.refreshis now called when theGame.READYevent 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
inputMouseCapturehas been removed, as this is now split into 3 new config options: inputMousePreventDefaultDownis a new config option that allows you to controlpreventDefaultcalls specifically on mouse down events. Set it viainput.mouse.preventDefaultDownin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultUpis a new config option that allows you to controlpreventDefaultcalls specifically on mouse up events. Set it viainput.mouse.preventDefaultUpin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultMoveis a new config option that allows you to controlpreventDefaultcalls specifically on mouse move events. Set it viainput.mouse.preventDefaultMovein the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultWheelis a new config option that allows you to controlpreventDefaultcalls specifically on mouse wheel events. Set it viainput.mouse.preventDefaultWheelin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.- The
MouseManager.captureproperty has been removed, as this is now split into 3 new config options (see below) MouseManager.preventDefaultDownis a new boolean property, set via theinputMousePreventDefaultDownconfig option that allows you to toggle capture of mouse down events at runtime.MouseManager.preventDefaultUpis a new boolean property, set via theinputMousePreventDefaultUpconfig option that allows you to toggle capture of mouse up events at runtime.MouseManager.preventDefaultMoveis a new boolean property, set via theinputMousePreventDefaultMoveconfig option that allows you to toggle capture of mouse move events at runtime.MouseManager.preventDefaultWheelis a new boolean property, set via theinputMousePreventDefaultWheelconfig option that allows you to toggle capture of mouse wheel at runtime.- In the
MouseManagerthe 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
GamepadPluginwill now callrefreshPadsas 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 viathis.input.gamepad.pad1and 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._createdis 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.downwill 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
useHandCursorenabled, 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.shutdownmethod 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.processOverEventshas 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.tintTopLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTLwhich has now been removed.Tint.tintTopRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTRwhich has now been removed.Tint.tintBottomLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBLwhich has now been removed.Tint.tintBottomRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBRwhich has now been removed.- The property
Tint._isTintedhas been removed as it's no longer required. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they now read the color value asoutTint.bgrinstead ofoutTint.rgb. This allows the colors to remain in RGB order within the Tint component. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they no longer have a 3-way check on theoutTintEffectvalue. - The
Multi Pipeline,Bitmap Text,Render Texture,Text,TileSpriteandCameranow all read the tint values from the public properties instead of the private_tintTLetc ones. They also now set thetintEffectvalue directly from thetintFillproperty, removing another conditional check. - The function
GetColorFromValuehas been removed as it's no longer used internally. - The
Rope.tintFillproperty is now a boolean, not an integer, and can no longer take2as 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
getTintAppendFloatAlphaAndSwaphave been replaced withgetTintAppendFloatAlphainstead. - As a result of the change to the shader, the Multi Pipeline now uses the
WebGLRenderer.whiteTextureandtintEffectmode 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.whiteTextureis 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
TextureManagernow generates a new texture with the key__WHITEdurings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines. Config.images.whiteis 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
Bodyclass has a new boolean propertypushable(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.setPushableis a new chainable method that allows you to set thepushablestate of a Body.Arcade.Components.Pushableis 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.disableUpdateis a new method that will prevent the Arcade Physics Worldupdatemethod 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.enableUpdateis 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.customUpdateis a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. Iftruethe World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)Physics.Arcade.Body.setCollideWorldBoundsnow has a new optional parameteronWorldBoundswhich allows you to enable the Body'sonWorldBoundsproperty in the same call (thanks @samme)ArcadePhysics.Body.setMaxVelocityXis a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)ArcadePhysics.Body.setMaxVelocityYis a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)- The
PhysicsGroupconfig now has two new optional propertiesmaxVelocityXandmaxVelocityYwhich allows you to set the maximum velocity on bodies added to the Group (thanks @samme) - The
Arcade.Body.resetFlagsmethod has a new optional boolean parameterclear. If set, it clears thewasTouchingflags on the Body. This happens automatically whenBody.resetis called. Previous to this, the flags were not reset until the next physics step (thanks @samme) Physics.Arcade.ProcessXis a new set of functions, called by theSeparateXfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Physics.Arcade.ProcessYis a new set of functions, called by theSeparateYfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Arcade.Body.centervalues 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.
AtlasJSONFileno longer stores the JSON in the JSON Cache once the texture has been created.AtlasXMLFileno longer stores the XML in the XML Cache once the texture has been created.UnityAtlasFileno longer stores the Text in the Text Cache once the texture has been created.BitmapFontFileno longer stores the XML in the XML Cache once the texture has been created.- You can now use
TextureManager.removeto 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#RESIZEevent no longer sends theresolutionas a parameter. - The
BaseCamera.resolutionproperty has been removed. - The internal private
BaseCamera._cx,_cy,_cwand_chproperties has been removed, usex,y,widthandheightinstead. - The
BaseCamera.preRendermethod no longer receives or uses theresolutionparameter. - The
Camera.preRendermethod no longer receives or uses theresolutionparameter. - The
CameraManager.onResizemethod no longer receives or uses theresolutionparameter. - The
Core.Config.resolutionproperty has been removed. - The
TextStyle.resolutionproperty 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
CanvasRendererno longer reads or uses the Game Config resolution property. - The
PipelineManager.resizemethod along withWebGLPipeline.resizeand anything else that extends them no longer receives or uses theresolutionparameter. - The
WebGLRenderer.resizeandonResizemethods no longer receives or uses theresolutionparameter. - The
ScaleManager.resolutionproperty 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.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Intersects.GetLineToPointsis 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.GetRaysFromPointToPolygonis 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.Translateis a new function that allows you to translate all the points of a polygon by the given values.Geom.Polygon.Simplifyis 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.setInt1ivwill allow you to look-up and set a 1iv uniform on the given shader.Phaser.Types.Math.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.getTweensOfhas a new parameterincludePending. 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.hasBootedis 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 theWebGLRenderer.addPipelinemethod, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)- The WebGL Renderer will now add the pipelines during the
bootmethod, instead ofinit. - You can now use
this.rendererfrom within a Scene, as it's now a Scene-level property and part of the Injection Map. Clock.addEventcan now take an existingTimerEventobject, as well as a config object. If aTimerEventis 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.removeEventis a new method that allows you to remove aTimerEvent, or an array of them, from all internal lists of the current Clock.Group.getMatchingis a new method that will return any members of the Group that match the given criteria, such asgetMatching('visible', true)(thanks @atursams)Utils.Array.SortByDigitsis 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 callingGroup.createMultipleorGroup.createFromConfig, can now accept the following new properties:setOrigin: { x, y, stepX, stepY }which are applied to the items created by the Group.Transform.copyPositionis a new method that will copy the position from the given object to the Game Object (thanks @samme)- The
Text.MeasureTextfunction, 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 newactualBoundingBoxAscentfunctions 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.GetCalcMatrixis 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,StarandTriangle. This dramatically reduces the amount of duplicate code across the API.Utils.Array.Matrix.Translateis a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.Vertor3.addScaleis 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
easeParamsin the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh) BitmapMask.createMaskis 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.clearMaskwill 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.Quaternionnow has a new propertyonChangeCallbackwhich, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.- The
Quaternion.setmethod has a new optional boolean parameterupdate(defaults totrue), which will call theonChangeCallbackif set. Quaternion.setFromEuleris a new method that will set the quaternion from the givenEulerobject, optionally calling theonChangeCallbackin the process.Quaternion.setFromRotationMatrixis a new method that will set the rotation of the quaternion from the given Matrix4.Vector3.setFromMatrixPositionis a new method that will set the components of the Vector3 based on the position of the given Matrix4.Vector3.setFromMatrixColumnis a new method that will set the components of the Vector3 based on the specified Matrix4 column.Vector3.fromArrayis a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.Vector3.minis a new method that will set the components of the Vector3 based on theMain.minbetween it and the given Vector3.Vector3.maxis a new method that will set the components of the Vector3 based on theMain.maxbetween it and the given Vector3.Vector3.addVectorsis a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.Vector3.addScalaris a new method that will multiply the components of the Vector3 by the scale value given.Vector3.applyMatrix3is a new method that will take a Matrix3 and apply it to the Vector3.Vector3.applyMatrix4is a new method that will take a Matrix4 and apply it to the Vector3.Vector3.projectViewMatrixis a new method that multiplies the Vector3 by the given view and projection matrices.Vector3.unprojectViewMatrixis a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.Matrix4.setValuesis a new method that allows you to set all of the matrix components individually. Most internal methods now use this.Matrix.multiplyToMat4is a new method that multiplies a Matrix4 by the givensrcMatrix4 and stores the results in theoutMatrix4.Matrix4.fromRotationXYTranslationis a new method that takes the rotation and position vectors and builds this Matrix4 from them.Matrix4.getMaxScaleOnAxisis a new method that will return the maximum axis scale from the Matrix4.Matrix4.lookAtRHis a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.Matrix4.transformis a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.Matrix4.multiplyMatricesis a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.Matrix4.premultiplyis a new method that takes a Matrix4 and multiplies it by the current Matrix4.Matrix4.getInverseis a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.WebGLRenderer.instancedArraysExtensionis a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.WebGLRenderer.vaoExtensionis 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.Earcutand is fully documented. Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself. - The constant
Phaser.Renderer.WebGL.BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.FLOATvalue has been removed as it wasn't used internally. Pointer.downTimenow 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.upTimenow 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.getDurationmethod now uses the new PointerdownTimeandupTimevalues, 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
BaseShaderdefault vertex shader now includes theoutTexCoordvec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok) - When using the
GameObjectCreatorforContainersyou can now specify thechildrenproperty in the configuration object. WebGLRenderer.finalTypeis a new boolean property that signifies if the current Game Object being rendered is the final one in the list.- The
WebGLRenderer.updateCanvasTexturemethod will now setgl.UNPACK_PREMULTIPLY_ALPHA_WEBGLto 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.JSONHashwill now perform ahasOwnPropertycheck when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes fromJSON.parse. Fix #4768 (thanks @RollinSafary)- The
Camera3DPlugin 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.seekwill 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.previousPipelineis a new property that is set during a call toclearPipelineand used during calls torebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.- The
WebGLRenderer.rebindPipelinemethod has been changed slightly. Previously, you had to specify thepipelineInstance, but this is now optional. If you don't, it will use the newpreviousPipelineproperty instead. If not set, or none given, it will now return without throwing gl errors as well. - If
inputWindowEventsis set in the Game Config, then theMouseManagerwill now listen for the events onwindow.topinstead of justwindow, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in atry/catchblock, as not all sites allow access towindow.top(specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow) MouseManager.isTopis a new boolean read-only property that flags if the mouse event listeners were attached towindow.top(true), or justwindow(false). By default Phaser will attemptwindow.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back towindowin those cases and set this property to false (thanks BunBunBun)Types.GameObjects.Text.GetTextSizeObjectis a new type def for the GetTextSize function results.Utils.Array.StableSorthas 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. Theinplacefunction has been removed, just callStableSort(array)directly now. All classes that usedStableSort.inplacehave 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.setOriginwill now callupdateDisplayOriginon the items array, otherwise the effects can't be seen when rendering.- You can now set the
ArcadeWorld.fixedStepproperty via theArcadeWorldConfigobject (thanks @samme) Utils.Array.NumerArraycan now accept thestartandendparameters in reverse order, i.e.10, 1will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.DataManager.Events.DESTROYis a new event that the Data Manager will listen for from its parent and then call its owndestroymethod when received.- The
Quaternionclass constructor will now default the values to0,0,0,1if they're not provided, making it an identity quaternion, rather than the0,0,0,0it was before. - You can now set the
ParticleEmitter.reservevalue via the emitter configuration object (thanks @vforsh) - Setting the
pixelArtconfig option will now setantialiasGLtofalse, as well asantialias. Fix #5309 (thanks @Vegita2) - The
Shapeclass now includes theComputedSizecomponent properties and methods directly in the class, rather than applying as a mixin.setSizeis now flagged as beingprivate, 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.maxParallelDownloadsvalue is now set to 6 if running on Android, or 32 on any other OS. This avoidsnet::ERR_FAILEDissues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary) WebGLRenderer.defaultScissoris a new property that holds the default scissor dimensions for the renderer. This is modified duringresizeand avoids continuous array generation in thepreRenderloop.- When running an Arcade Physics
overlaptest against aStaticBody, it will no longer set theblockedstates 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
LineGame 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
Quaternionclass now has 4 new private properties:_x,_y,_zand_wand 4 new getters and setters for the public versions. It also now passes most methods viasetto allow for the onChange callback to be invoked. This does not change the public-facing API. Groupnow extendsEventEmitter, allowing you to emit custom events from within a Group.Device.Audio.wavnow usesaudio/wavas thecanPlayTypecheck string, instead ofaudio/wav; codecs="1", which should allow iOS13 to play wav files again.- In the
Loader.FileTypes.TextFileconfig you can now override the type and cache destination for the file. Loader.MultiFilewill 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 fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.RenderTexture.fillwould 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
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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
ProcessQueuewas emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar) - The
GridAlignaction didn't work if only theheightparameter was set. Fix #5019 (thanks @halilcakar) - The
Color.HSVToRGBfunction has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX) - Previously, the
easeParamsarray within a Tweenspropsobject, 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.setRenderToTextureitszoomandrotationvalues would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok) GameObjects.Shape.Gridwould render a white fill even if you passedundefinedas the fill color in the constructor. It now doesn't render cells if no fill color is given.- The
onMouseevents in the Input Manager didn't reset theactivePointerproperty 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
GetScreenOrientationfunction will now check forwindow.orientationfirst, 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 emitorientationchangeevents correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu) Time.Clock.addEventcan now take an instance of aTimerEventas its parameter. Fix #5294 (thanks @samme @EmilSV)GameConfig.audionow defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)- The
Loader.pathwas 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.getMatchingwould always return an empty array. It now returns matching children (thanks @samme)- The
ParticleManagerWebGLRenderernow 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
ParticleManagerCanvasRenderernow calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also usessetToContextinternally. 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
GraphicsWebGL Renderer will now default topathOpen = true. This fixes issues under WebGL where, for example, adding an arc and callingstrokePath, without first callingbeginPathwill no longer cause rendering artefacts when WebGL tries to close the path with a single tri. Graphics.strokeRoundedRectnow issuesmoveTocommands 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
snapshotin WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in theWebGLSnapshotfunction. Fix #4956 (thanks @gammafp @telinc1) - You can now draw a
Groupto aRenderTexture. 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.MoveTofunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.DOM.GetInnerHeightfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Bobclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsManagerclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsPluginclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Particles.EmitterOpclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.GetTextSizefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.MeasureTextfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.TextStylefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Input.CreatePixelPerfectHandlerfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapCircfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapRectfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Tilemapnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Componentsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.MatterGameObjectclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.PointerConstraintclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetPhysicsPluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetScenePluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Structs.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Tilemaps.Parsers.Tiledfunction has now been exposed on the Phaser namespace (thanks @samme) - Every single
Tilemap.Componentfunction 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:
TextureTintPipelineis now called theMultiPipeline.TextureTintStripPipelineis now called theRopePipeline.ForwardDiffuseLightPipelineis now called theLightPipeline.
To match the new pipeline names, the shader source code has also been renamed.
ForwardDiffuse.fragis now calledLight.frag.TextureTint.fragis now calledMulti.frag.TextureTint.vertis now calledMulti.vert.
Other pipeline changes are as follows:
Types.Renderer.WebGL.WebGLPipelineConfigis a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.Types.Renderer.WebGL.WebGLPipelineAttributesConfigis 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
rendererproperty automatically, so it's no longer required in the config. - All pipelines will now work out the
glproperty automatically, so it's no longer required in the config. - All pipelines will now extract the
nameproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexCapacityproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexSizeproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexDataproperty from the config, allowing you to set it externally. - All pipelines will now extract the
attributesproperty from the config, allowing you to set it externally. - All pipelines will now extract the
topologyproperty from the config, allowing you to set it externally. - The
WebGLPipeline.shouldFlushmethod now accepts an optional parameteramount. If given, it will returntrueif 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
RopePipelinenow extendsMultiPipelineand 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.set1fwill set a 1f uniform based on the given name.WebGLPipeline.set2fwill set a 2f uniform based on the given name.WebGLPipeline.set3fwill set a 3f uniform based on the given name.WebGLPipeline.set4fwill set a 4f uniform based on the given name.WebGLPipeline.set1fvwill set a 1fv uniform based on the given name.WebGLPipeline.set2fvwill set a 2fv uniform based on the given name.WebGLPipeline.set3fvwill set a 3fv uniform based on the given name.WebGLPipeline.set4fvwill set a 4fv uniform based on the given name.WebGLPipeline.set1ivwill set a 1iv uniform based on the given name.WebGLPipeline.set2ivwill set a 2iv uniform based on the given name.WebGLPipeline.set3ivwill set a 3iv uniform based on the given name.WebGLPipeline.set4ivwill set a 4iv uniform based on the given name.WebGLPipeline.set1iwill set a 1i uniform based on the given name.WebGLPipeline.set2iwill set a 2i uniform based on the given name.WebGLPipeline.set3iwill set a 3i uniform based on the given name.WebGLPipeline.set4iwill set a 4i uniform based on the given name.WebGLPipeline.setMatrix2fvwill set a matrix 2fv uniform based on the given name.WebGLPipeline.setMatrix3fvwill set a matrix 3fv uniform based on the given name.WebGLPipeline.setMatrix4fvwill 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.setFloat1has been removed. Please useset1finstead.WebGLPipeline.setFloat2has been removed. Please useset2finstead.WebGLPipeline.setFloat3has been removed. Please useset3finstead.WebGLPipeline.setFloat4has been removed. Please useset4finstead.WebGLPipeline.setFloat1vhas been removed. Please useset1fvinstead.WebGLPipeline.setFloat2vhas been removed. Please useset2fvinstead.WebGLPipeline.setFloat3vhas been removed. Please useset3fvinstead.WebGLPipeline.setFloat4vhas been removed. Please useset4fvinstead.WebGLPipeline.setInt1has been removed. Please useset1iinstead.WebGLPipeline.setInt2has been removed. Please useset2iinstead.WebGLPipeline.setInt3has been removed. Please useset3iinstead.WebGLPipeline.setInt4has been removed. Please useset4iinstead.WebGLPipeline.setMatrix1has been removed. Please usesetMatrix2fvinstead.WebGLPipeline.setMatrix2has been removed. Please usesetMatrix3fvinstead.WebGLPipeline.setMatrix3has been removed. Please usesetMatrix4fvinstead.
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.pipelinesis no longer a plain object containing pipeline instances. It's now an instance of thePipelineManagerclass. This instance is created during the init and boot phase of the renderer.- The
WebGLRenderer.currentPipelineproperty no longer exists, instead usePipelineManager.current. - The
WebGLRenderer.previousPipelineproperty no longer exists, instead usePipelineManager.previous. - The
WebGLRenderer.hasPipelinemethod no longer exists, instead usePipelineManager.has. - The
WebGLRenderer.getPipelinemethod no longer exists, instead usePipelineManager.get. - The
WebGLRenderer.removePipelinemethod no longer exists, instead usePipelineManager.remove. - The
WebGLRenderer.addPipelinemethod no longer exists, instead usePipelineManager.add. - The
WebGLRenderer.setPipelinemethod no longer exists, instead usePipelineManager.set. - The
WebGLRenderer.rebindPipelinemethod no longer exists, instead usePipelineManager.rebind. - The
WebGLRenderer.clearPipelinemethod no longer exists, instead usePipelineManager.clear.
The Pipeline Manager also offers the following new features:
- The
PipelineManager.resizemethod automatically handles resize events across all pipelines. - The
PipelineManager.preRendermethod calls the pre-render method of all pipelines. - The
PipelineManager.rendermethod calls the render method of all pipelines. - The
PipelineManager.postRendermethod calls the post-render method of all pipelines. - The
PipelineManager.setMultimethod automatically binds the Multi Texture Pipeline, Phaser's default. - The
PipelineManager.clearmethod will clear the pipeline, store it inpreviousand free the renderer. - The
PipelineManager.rebindmethod will reset the rendering context and restore thepreviouspipeline, if set.
New constants have been created to help you reference a pipeline without needing to use strings:
Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINEfor the Bitmap Mask Pipeline.Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINEfor the Light 2D Pipeline.Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINEfor the Single Pipeline.Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINEfor the Multi Pipeline.Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINEfor 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture that was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLPipeline.forceZerois a new property that informs Game Objects if the pipeline requires a zero bound texture unit.WebGLPipeline.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLRenderer.unbindTexturesis a new method that will activate and then null bind all WebGL textures.Renderer.WebGL.Utils.parseFragmentShaderMaxTexturesis 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis a new method that will look-up and return a normal map for the given object.
Lights
Light.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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.MVPis a new namespace under which the Model View Projection functions now live.projIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectIdentityprojPerspis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectPerspectivemodelRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateXmodelRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateYmodelRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateZviewLoadis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoadviewRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateXviewRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateYviewRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateZviewScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewScaleviewTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewTranslatemodelIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.IdentitymodelScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ScalemodelTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.TranslateviewIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewIdentityviewLoad2Dis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoad2DprojOrthois now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectOrthoPhaser.Renderer.WebGL.MVP.SetIdentityis a new function the others use, to save on space.
BitmapText - New Features, Updates and API Changes
BitmapText.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycoordinates. The character data includes the code, position, dimensions, and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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
setMaxWidthonDynamicBitmapText, 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_SCENEis 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_SCENEis 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_SCENEis 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_SCENEis 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.addedToSceneis 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.removedFromSceneis 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 theremovedFromScenemethod now. - The
Containerwill 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.eventsis a new property that references the Scene's Event Emitter. This is now used internally.DisplayList.addChildCallbackis a new method that overrides the List callback and fires the new ADDED events.DisplayList.removeChildCallbackis a new method that overrides the List callback and fires the new REMOVED events.GameObjectCreator.eventsis a new property that references the Scene's Event Emitter. This is now used internally.GameObjectFactory.eventsis a new property that references the Scene's Event Emitter. This is now used internally.ProcessQueue.checkQueueis a new boolean property that will make sure only unique objects are added to the Process Queue.- The
Update Listnow uses the newcheckQueueproperty to ensure no duplicate objects are on the active list. DOMElementFactory,ExternFactory,ParticleManagerFactor,RopeFactoryandSpriteFactoryall no longer add the objects to the Update List, this is now handled by the ADDED events instead.Sprite,Rope,ParticleEmitterManager,ExternandDOMElementnow all override theaddedToSceneandremovedFromScenecallbacks 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.
SpineContaineris a new Game Object available viathis.add.spineContainerto 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.runtimeswhich will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo intoplugins/spine/in order for this to work and then runnpm 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-zeroerror 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.setAnimationmethod will now use thetrackIndexparameter ifignoreIfPlayingis set and run the check against this track index. Fix #4842 (thanks @vinerz) - The
SpineFilewill 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
destroymethod 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.gameDestroyis a new method that is called if the Game instance emits adestroyevent. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.SpineFilewill 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)SpineFilenow 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
Animationclass no longer extendsEventEmitter, 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_KEYevents have been removed. Instead, please use the new events which all carry theframeKeyparameter, which can be used to handle frame specific events. The only exception to this isANIMATION_COMPLETE_KEY, which is a key specific version of the completion event. ANIMATION_UPDATE_EVENTis a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.ANIMATION_STOP_EVENTis a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of thestopmethods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)- The Game Object
Component.Animationcomponent has been renamed toAnimationStateand has moved namespace. It's now inPhaser.Animationsinstead ofGameObjects.Componentsto help differentiate it from theAnimationclass when browsing the documentation. - The
play,playReverse,playAfterDelay,playAfterRepeatandchainSprite and Animation Component methods can now all take aPhaser.Types.Animations.PlayAnimationConfigconfiguration object, as well as a string, as thekeyparameter. 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.createis 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.generateFrameNumbersis 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.generateFrameNamesis 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,playAfterDelayandplayAfterRepeatwill 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.skipMissedFramesis 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.addMixis 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.getMixis a new method that will return the mix duration between the two given animations.AnimationManager.removeMixis a new method that will remove the mixture between either two animations, or all mixtures for the given animation.AnimationState.removeis a new method that will remove a locally stored Animation instance from a Sprite.AnimationState.getis a new method that will return a locally stored Animation instance from the Sprite.AnimationState.existsis a new method that will check if a locally stored Animation exists on the Sprite.- The internal
AnimationState.removemethod has been renamed toglobalRemove. AnimationState.textureManageris a new property that references the global Texture Manager.AnimationState.animsis a new property that contains locally created Animations in a Custom Map.AnimationState.playandSprite.playno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.AnimationState.playReverseandSprite.playReverseno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.- The
AnimationState.delayedPlaymethod has been renamed toplayAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration. - The
AnimationState.stopOnRepeatmethod has been renamed tostopAfterRepeat - The
AnimationState.getCurrentKeymethod has been renamed togetName. AnimationState.getFrameNameis a new method that will return the key of the current Animation Frame, if an animation has been loaded.AnimationState.playAfterDelayandSprite.playAfterDelayare new methods that will play the given animation after the delay in ms expires.AnimationState.playAfterRepeatandSprite.playAfterRepeatare 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.chainmethod is now available on the Sprite class. - The
AnimationState.stopAfterDelaymethod is now available on the Sprite class. - The
AnimationState.stopAfterRepeatmethod is now available on the Sprite class. - The
AnimationState.stopOnFramemethod is now available on the Sprite class. AnimationManager.createFromAsepriteis 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.AnimationStatenow 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 optionalPlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.- The
PlayAnimationConfig.frameRateproperty lets you optionally override the animation frame rate. - The
PlayAnimationConfig.durationproperty lets you optionally override the animation duration. - The
PlayAnimationConfig.delayproperty lets you optionally override the animation delay. - The
PlayAnimationConfig.repeatproperty lets you optionally override the animation repeat counter. - The
PlayAnimationConfig.repeatDelayproperty lets you optionally override the animation repeat delay value. - The
PlayAnimationConfig.yoyoproperty lets you optionally override the animation yoyo boolean. - The
PlayAnimationConfig.showOnStartproperty lets you optionally override the animation show on start value. - The
PlayAnimationConfig.hideOnCompleteproperty lets you optionally override the animation hide on complete value. - The
PlayAnimationConfig.startFrameproperty lets you optionally set the animation frame to start on. - The
PlayAnimationConfig.timeScaleproperty lets you optionally set the animation time scale factor. AnimationState.delayCounteris a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animationSTARTevents fire. Fix #4426 (thanks @bdaenen)AnimationState.hasStartedis 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.showOnStartis a new boolean property that controls if the Game Object should havesetVisible(true)called on it when the animation starts.AnimationState.hideOnCompleteis a new boolean property that controls if the Game Object should havesetVisible(false)called on it when the animation completes.- The
AnimationState.chainmethod docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does! - The
AnimationState.setDelaymethod has been removed. It never actually worked and you can now perform the same thing by calling eitherplayAfterDelayor setting thedelayproperty in the play config. - The
AnimationState.getDelaymethod has been removed. You can now read thedelayproperty directly. - The
AnimationState.setRepeatmethod has been removed. You can achieve the same thing by setting therepeatproperty in the play config, or adjusting the publicrepeatCounterproperty if the animation has started. AnimationState.handleStartis a new internal private method that handles the animation start process.AnimationState.handleRepeatis a new internal private method that handles the animation repeat process.AnimationState.handleStopis a new internal private method that handles the animation stop process.AnimationState.handleCompleteis a new internal private method that handles the animation complete process.AnimationState.emitEventsis a new internal private method that emits animation events, cutting down on duplicate code.- The
AnimationState.restartmethod has a new optional boolean parameterresetRepeatswhich controls if you want to reset the repeat counter during the restart, or not. Animation.getTotalFramesis a new method that will return the total number of frames in the animation. You can access it viathis.anims.currentAnim.getTotalFramesfrom a Sprite.Animation.calculateDurationis a new method that calculates the duration, frameRate and msPerFrame for a given animation target.- The
BuildGameObjectAnimationfunction now uses thePlayAnimationConfigobject to set the values. Sprite.playReverseis a new method that allows you to play the given animation in reverse on the Sprite.Sprite.playAfterDelayis a new method that allows you to play the given animation on the Sprite after a delay.Sprite.stopis a new method that allows you to stop the current animation on the Sprite.AnimationManager.loadhas been removed as it's no longer required.AnimationManager.staggerPlayhas been fixed so you can now pass in negative stagger values.AnimationManager.staggerPlayhas a new optional boolean parameterstaggerFirst, which allows you to either include or exclude the first child in the stagger calculations.- The
Animation.completeAnimationmethod has been removed as it's no longer required. - The
Animation.loadmethod has been removed as it's no longer required. - The
Animation.setFramemethod has been removed as it's no longer required. - The
Animation.getFirstTickmethod has no longer needs theincludeDelayparameter, as it's handled byAnimationStatenow. - The
Animation.getFramesmethod has a new optional boolean parametersortFrameswhich will run a numeric sort on the frame names after constructing them, if a string-based frame is given. Types.Animations.Animationhas a new boolean propertysortFrames, which lets Phaser numerically sort the generated frames.AnimationState.timeScaleis a new public property that replaces the old private_timeScaleproperty.AnimationState.delayis a new public property that replaces the old private_delayproperty.AnimationState.repeatis a new public property that replaces the old private_repeatproperty.AnimationState.repeatDelayis a new public property that replaces the old private_repeatDelayproperty.AnimationState.yoyois a new public property that replaces the old private_yoyoproperty.AnimationState.inReverseis a new public property that replaces the old private_reverseproperty.AnimationState.startAnimationis a new public method that replaces the old private_startAnimationmethod.- The
AnimationState.getProgressmethod has been fixed so it will return correctly if the animation is playing in reverse. - The
AnimationState.globalRemovemethod will now always be called when an animation is removed from the global Animation Manager, not just once. - The
AnimationState.getRepeatmethod has now been removed. You can get the value from therepeatproperty. - The
AnimationState.setRepeatDelaymethod has now been removed. You can set the value using therepeatDelayconfig property, or changing it at run-time. AnimationState.completeis a new method that handles the completion in animation playback.- The
AnimationState.setTimeScalemethod has now been removed. You can set the value using thetimeScaleconfig property, or changing it at run-time. - The
AnimationState.getTimeScalemethod has now been removed. You can read the value using thetimeScaleproperty. - The
AnimationState.getTotalFramesmethod has been fixed and won't error if called when no animation is loaded. - The
AnimationState.setYoyomethod has now been removed. You can set the value using theyoyoconfig property, or changing it at run-time. - The
AnimationState.getYoyomethod has now been removed. You can read the value using theyoyoproperty. - The
AnimationState.stopAfterRepeatmethod now has an optional parameterrepeatCount, 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.updateFramemethod has now been removed. Everything is handled bysetCurrentFrameinstead, which removes one extra step out of the update process. GenerateFrameNameswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswould 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.GenerateFrameNumberscan now accept thestartandendparameters in reverse order, meaning you can now do{ start: 10, end: 1 }to create the animation in reverse.GenerateFrameNamescan now accept thestartandendparameters 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.TilemapOrientationTypeis a new type def that holds the 4 types of map orientation now supported.- The
Tile.updatePixelXYmethod now updates the tile XY position based on map type. Tilemap.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.DynamicTilemapLayer.isoCullDistancesis 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.isoCullDistancesis 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.orientationis a new property that holds the tilemap layers orientation constant.LayerData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.MapData.orientationis a new property that holds the tilemap layers orientation constant.MapData.hexSideLengthis a new property that holds the length of the hexagon sides, if using Hexagonal Tilemaps.Tilemaps.Components.HexagonalWorldToTileYis a new function that converts a world Y coordinate to hexagonal tile Y coordinate.Tilemaps.Components.StaggeredWorldToTileYis a new function that converts a world Y coordinate to staggered tile Y coordinate.Tilemaps.Components.HexagonalWorldToTileXYis a new function that converts world coordinates to hexagonal tile coordinates.Tilemaps.Components.IsometricWorldToTileXYis a new function that converts world coordinates to isometric tile coordinates.Tilemaps.Components.StaggeredWorldToTileXYis a new function that converts world coordinates to staggered tile coordinates.Tilemaps.Components.HexagonalTileToWorldYis a new function that converts a hexagonal Y coordinate to a world coordinate.Tilemaps.Components.StaggeredTileToWorldYis a new function that converts a staggered Y coordinate to a world coordinate.Tilemaps.Components.HexagonalTileToWorldXYis a new function that converts hexagonal tile coordinates to world coordinates.Tilemaps.Components.IsometricTileToWorldXYis a new function that converts isometric tile coordinates to world coordinates.Tilemaps.Components.StaggeredTileToWorldXYis a new function that converts staggered tile coordinates to world coordinates.Tilemaps.Components.GetTileToWorldXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetTileToWorldXXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetWorldToTileXYFunctionis a new function that returns the correct conversion function to use.Tilemaps.Components.GetCullTilesFunctionis a new function that returns the correct culling function to use.Tilemaps.Components.HexagonalCullTilesis a new function that culls tiles in a hexagonal map.Tilemaps.Components.StaggeredCullTilesis a new function that culls tiles in a staggered map.Tilemaps.Components.IsometricCullTilesis a new function that culls tiles in a isometric map.Tilemaps.Components.CullBoundsis a new function that calculates the cull bounds for an orthogonal map.Tilemaps.Components.HexagonalCullBoundsis a new function that calculates the cull bounds for a hexagonal map.Tilemaps.Components.StaggeredCullBoundsis a new function that calculates the cull bounds for a staggered map.Tilemaps.Components.RunCullis a new function that runs the culling process from the combined bounds and tilemap.Tilemap._convertis 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.Meshis 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.Vertexis a new class that encapsulates all of the data required for a single vertex, including position, uv, normals, color and alpha.Geom.Mesh.Faceis a new class that consists of references to the threeVertexinstances that construct a single Face in a Mesh and provides methods for manipulating them.Geom.Mesh.GenerateVertsis a new function that will return an array ofVertexandFaceobjects 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.GenerateGridVertsis a new function that will generate a series ofVertexobjects in a grid format, based on the givenGenerateGridConfigconfig 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.GenerateObjVertsis a new function that will generate a series ofVertexobjects 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.ParseObjis a new function that will parse a triangulated Wavefront OBJ file into model data into a format that theGenerateObjVertsfunction can consume.Geom.Mesh.ParseObjMaterialis 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.RotateFaceis a new function that will rotate a Face by a given amount, based on an optional center of rotation.Loader.OBJFileis 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
MeshFactorysignatures have changed toscene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas. Note the way the Texture and Frame parameters now comes first.indiciesis a new parameter that allows you to provide indexed vertex data to create the Mesh from, where theindiciesarray holds the vertex index information. The final list of vertices is built from this index along with the provided vertices and uvs arrays. Theindiciesarray is optional. If your data is not indexed, then simply passnullor an empty array for this parameter. - The
MeshGame 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.addVerticesis 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.addVerticesFromObjis a new method that will add the model data from a loaded Wavefront OBJ file to a Mesh. You load it via the newOBJFilewith athis.load.objcall, 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.hideCCWis 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.modelPositionis a new Vector3 property that allows you to translate the position of all vertices in the Mesh.Mesh.modelRotationis a new Vector3 property that allows you to rotate all vertices in the Mesh.Mesh.modelScaleis a new Vector3 property that allows you to scale all vertices in the Mesh.Mesh.panXis a new function that will translate the view position of the Mesh on the x axis.Mesh.panYis a new function that will translate the view position of the Mesh on the y axis.Mesh.panZis a new function that will translate the view position of the Mesh on the z axis.Mesh.updateProjectionMatrixis a new method that allows you to set the projection matrix based on the given size, fov, near and far values.Mesh.clearis a new method that will destroy all Faces and Vertices and clear the Mesh.Mesh.depthSortis a new method that will run a depth sort across all Faces in the Mesh by sorting them based on their average depth.Mesh.addVertexis a new method that allows you to add a new single Vertex into the Mesh.Mesh.addFaceis a new method that allows you to add a new Face into the Mesh. A Face must consist of 3 Vertex instances.Mesh.getFaceCountnew is a new method that will return the total number of Faces in the Mesh.Mesh.getVertexCountnew is a new method that will return the total number of Vertices in the Mesh.Mesh.getFacenew is a new method that will return a Face instance from the Mesh based on the given index.Mesh.getFaceAtnew 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.verticesis now an array ofGameObject.Vertexinstances, not a Float32Array.Mesh.facesis a new array ofGameObject.Faceinstances, which is populated during a call to methods likeaddVerticesoraddModel.Mesh.totalRenderedis a new property that holds the total number of Faces that were rendered in the previous frame.Mesh.setDebugis 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
BringToTopto 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
MeshGame Object now extends theSingleAlphacomponent 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 standardsetAlphamethods. 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
colorsparameter in the constructor, factory method andaddVerticesmethod. 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
alphasparameter in the constructor, factory method andaddVerticesmethod. If a number, instead of an array, it will be used as the alpha for all vertices created. Mesh.debugGraphicis a new property that holds the debug Graphics instance reference.Mesh.debugCallbackis a new property that holds the debug render callback.Mesh.renderDebugVertsis a new method that acts as the default render callback forsetDebugif none is provided.Mesh.preDestroyis a new method that will clean-up the Mesh arrays and debug references on destruction.Mesh.isDirtyis a new method that will check if any of the data is dirty, requiring the vertices to be transformed. This is called automatically inpreUpdateto avoid generating lots of math when nothing has changed.- The
Mesh.uvarray has been removed. All UV data is now bound in the Vertex instances. - The
Mesh.colorsarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.alphasarray has been removed. All color data is now bound in the Vertex instances. - The
Mesh.tintFillproperty is now abooleanand defaults tofalse.
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.refreshis now called when theGame.READYevent 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
inputMouseCapturehas been removed, as this is now split into 3 new config options: inputMousePreventDefaultDownis a new config option that allows you to controlpreventDefaultcalls specifically on mouse down events. Set it viainput.mouse.preventDefaultDownin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultUpis a new config option that allows you to controlpreventDefaultcalls specifically on mouse up events. Set it viainput.mouse.preventDefaultUpin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultMoveis a new config option that allows you to controlpreventDefaultcalls specifically on mouse move events. Set it viainput.mouse.preventDefaultMovein the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultWheelis a new config option that allows you to controlpreventDefaultcalls specifically on mouse wheel events. Set it viainput.mouse.preventDefaultWheelin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.- The
MouseManager.captureproperty has been removed, as this is now split into 3 new config options (see below) MouseManager.preventDefaultDownis a new boolean property, set via theinputMousePreventDefaultDownconfig option that allows you to toggle capture of mouse down events at runtime.MouseManager.preventDefaultUpis a new boolean property, set via theinputMousePreventDefaultUpconfig option that allows you to toggle capture of mouse up events at runtime.MouseManager.preventDefaultMoveis a new boolean property, set via theinputMousePreventDefaultMoveconfig option that allows you to toggle capture of mouse move events at runtime.MouseManager.preventDefaultWheelis a new boolean property, set via theinputMousePreventDefaultWheelconfig option that allows you to toggle capture of mouse wheel at runtime.- In the
MouseManagerthe 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
GamepadPluginwill now callrefreshPadsas 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 viathis.input.gamepad.pad1and 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._createdis 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.downwill 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
useHandCursorenabled, 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.shutdownmethod 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.processOverEventshas 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.tintTopLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTLwhich has now been removed.Tint.tintTopRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTRwhich has now been removed.Tint.tintBottomLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBLwhich has now been removed.Tint.tintBottomRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBRwhich has now been removed.- The property
Tint._isTintedhas been removed as it's no longer required. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they now read the color value asoutTint.bgrinstead ofoutTint.rgb. This allows the colors to remain in RGB order within the Tint component. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they no longer have a 3-way check on theoutTintEffectvalue. - The
Multi Pipeline,Bitmap Text,Render Texture,Text,TileSpriteandCameranow all read the tint values from the public properties instead of the private_tintTLetc ones. They also now set thetintEffectvalue directly from thetintFillproperty, removing another conditional check. - The function
GetColorFromValuehas been removed as it's no longer used internally. - The
Rope.tintFillproperty is now a boolean, not an integer, and can no longer take2as 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
getTintAppendFloatAlphaAndSwaphave been replaced withgetTintAppendFloatAlphainstead. - As a result of the change to the shader, the Multi Pipeline now uses the
WebGLRenderer.whiteTextureandtintEffectmode 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.whiteTextureis 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
TextureManagernow generates a new texture with the key__WHITEdurings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines. Config.images.whiteis 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
Bodyclass has a new boolean propertypushable(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.setPushableis a new chainable method that allows you to set thepushablestate of a Body.Arcade.Components.Pushableis 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.disableUpdateis a new method that will prevent the Arcade Physics Worldupdatemethod 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.enableUpdateis 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.customUpdateis a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. Iftruethe World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)Physics.Arcade.Body.setCollideWorldBoundsnow has a new optional parameteronWorldBoundswhich allows you to enable the Body'sonWorldBoundsproperty in the same call (thanks @samme)ArcadePhysics.Body.setMaxVelocityXis a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)ArcadePhysics.Body.setMaxVelocityYis a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)- The
PhysicsGroupconfig now has two new optional propertiesmaxVelocityXandmaxVelocityYwhich allows you to set the maximum velocity on bodies added to the Group (thanks @samme) - The
Arcade.Body.resetFlagsmethod has a new optional boolean parameterclear. If set, it clears thewasTouchingflags on the Body. This happens automatically whenBody.resetis called. Previous to this, the flags were not reset until the next physics step (thanks @samme) Physics.Arcade.ProcessXis a new set of functions, called by theSeparateXfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Physics.Arcade.ProcessYis a new set of functions, called by theSeparateYfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Arcade.Body.centervalues 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.
AtlasJSONFileno longer stores the JSON in the JSON Cache once the texture has been created.AtlasXMLFileno longer stores the XML in the XML Cache once the texture has been created.UnityAtlasFileno longer stores the Text in the Text Cache once the texture has been created.BitmapFontFileno longer stores the XML in the XML Cache once the texture has been created.- You can now use
TextureManager.removeto 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#RESIZEevent no longer sends theresolutionas a parameter. - The
BaseCamera.resolutionproperty has been removed. - The internal private
BaseCamera._cx,_cy,_cwand_chproperties has been removed, usex,y,widthandheightinstead. - The
BaseCamera.preRendermethod no longer receives or uses theresolutionparameter. - The
Camera.preRendermethod no longer receives or uses theresolutionparameter. - The
CameraManager.onResizemethod no longer receives or uses theresolutionparameter. - The
Core.Config.resolutionproperty has been removed. - The
TextStyle.resolutionproperty 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
CanvasRendererno longer reads or uses the Game Config resolution property. - The
PipelineManager.resizemethod along withWebGLPipeline.resizeand anything else that extends them no longer receives or uses theresolutionparameter. - The
WebGLRenderer.resizeandonResizemethods no longer receives or uses theresolutionparameter. - The
ScaleManager.resolutionproperty 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.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Intersects.GetLineToPointsis 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.GetRaysFromPointToPolygonis 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.Translateis a new function that allows you to translate all the points of a polygon by the given values.Geom.Polygon.Simplifyis 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.setInt1ivwill allow you to look-up and set a 1iv uniform on the given shader.Phaser.Types.Math.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.getTweensOfhas a new parameterincludePending. 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.hasBootedis 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 theWebGLRenderer.addPipelinemethod, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)- The WebGL Renderer will now add the pipelines during the
bootmethod, instead ofinit. - You can now use
this.rendererfrom within a Scene, as it's now a Scene-level property and part of the Injection Map. Clock.addEventcan now take an existingTimerEventobject, as well as a config object. If aTimerEventis 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.removeEventis a new method that allows you to remove aTimerEvent, or an array of them, from all internal lists of the current Clock.Group.getMatchingis a new method that will return any members of the Group that match the given criteria, such asgetMatching('visible', true)(thanks @atursams)Utils.Array.SortByDigitsis 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 callingGroup.createMultipleorGroup.createFromConfig, can now accept the following new properties:setOrigin: { x, y, stepX, stepY }which are applied to the items created by the Group.Transform.copyPositionis a new method that will copy the position from the given object to the Game Object (thanks @samme)- The
Text.MeasureTextfunction, 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 newactualBoundingBoxAscentfunctions 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.GetCalcMatrixis 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,StarandTriangle. This dramatically reduces the amount of duplicate code across the API.Utils.Array.Matrix.Translateis a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.Vertor3.addScaleis 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
easeParamsin the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh) BitmapMask.createMaskis 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.clearMaskwill 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.Quaternionnow has a new propertyonChangeCallbackwhich, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.- The
Quaternion.setmethod has a new optional boolean parameterupdate(defaults totrue), which will call theonChangeCallbackif set. Quaternion.setFromEuleris a new method that will set the quaternion from the givenEulerobject, optionally calling theonChangeCallbackin the process.Quaternion.setFromRotationMatrixis a new method that will set the rotation of the quaternion from the given Matrix4.Vector3.setFromMatrixPositionis a new method that will set the components of the Vector3 based on the position of the given Matrix4.Vector3.setFromMatrixColumnis a new method that will set the components of the Vector3 based on the specified Matrix4 column.Vector3.fromArrayis a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.Vector3.minis a new method that will set the components of the Vector3 based on theMain.minbetween it and the given Vector3.Vector3.maxis a new method that will set the components of the Vector3 based on theMain.maxbetween it and the given Vector3.Vector3.addVectorsis a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.Vector3.addScalaris a new method that will multiply the components of the Vector3 by the scale value given.Vector3.applyMatrix3is a new method that will take a Matrix3 and apply it to the Vector3.Vector3.applyMatrix4is a new method that will take a Matrix4 and apply it to the Vector3.Vector3.projectViewMatrixis a new method that multiplies the Vector3 by the given view and projection matrices.Vector3.unprojectViewMatrixis a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.Matrix4.setValuesis a new method that allows you to set all of the matrix components individually. Most internal methods now use this.Matrix.multiplyToMat4is a new method that multiplies a Matrix4 by the givensrcMatrix4 and stores the results in theoutMatrix4.Matrix4.fromRotationXYTranslationis a new method that takes the rotation and position vectors and builds this Matrix4 from them.Matrix4.getMaxScaleOnAxisis a new method that will return the maximum axis scale from the Matrix4.Matrix4.lookAtRHis a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.Matrix4.transformis a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.Matrix4.multiplyMatricesis a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.Matrix4.premultiplyis a new method that takes a Matrix4 and multiplies it by the current Matrix4.Matrix4.getInverseis a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.WebGLRenderer.instancedArraysExtensionis a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.WebGLRenderer.vaoExtensionis 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.Earcutand is fully documented. Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself. - The constant
Phaser.Renderer.WebGL.BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.FLOATvalue has been removed as it wasn't used internally. Pointer.downTimenow 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.upTimenow 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.getDurationmethod now uses the new PointerdownTimeandupTimevalues, 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
BaseShaderdefault vertex shader now includes theoutTexCoordvec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok) - When using the
GameObjectCreatorforContainersyou can now specify thechildrenproperty in the configuration object. WebGLRenderer.finalTypeis a new boolean property that signifies if the current Game Object being rendered is the final one in the list.- The
WebGLRenderer.updateCanvasTexturemethod will now setgl.UNPACK_PREMULTIPLY_ALPHA_WEBGLto 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.JSONHashwill now perform ahasOwnPropertycheck when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes fromJSON.parse. Fix #4768 (thanks @RollinSafary)- The
Camera3DPlugin 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.seekwill 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.previousPipelineis a new property that is set during a call toclearPipelineand used during calls torebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.- The
WebGLRenderer.rebindPipelinemethod has been changed slightly. Previously, you had to specify thepipelineInstance, but this is now optional. If you don't, it will use the newpreviousPipelineproperty instead. If not set, or none given, it will now return without throwing gl errors as well. - If
inputWindowEventsis set in the Game Config, then theMouseManagerwill now listen for the events onwindow.topinstead of justwindow, which should help in situations where the pointer is released outside of an embedded iframe. This check is wrapped in atry/catchblock, as not all sites allow access towindow.top(specifically in cross-origin iframe situations) Fix #4824 (thanks @rexrainbow) MouseManager.isTopis a new boolean read-only property that flags if the mouse event listeners were attached towindow.top(true), or justwindow(false). By default Phaser will attemptwindow.top, but this isn't possible in all environments, such as cross-origin iframes, so it will fall back towindowin those cases and set this property to false (thanks BunBunBun)Types.GameObjects.Text.GetTextSizeObjectis a new type def for the GetTextSize function results.Utils.Array.StableSorthas 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. Theinplacefunction has been removed, just callStableSort(array)directly now. All classes that usedStableSort.inplacehave 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.setOriginwill now callupdateDisplayOriginon the items array, otherwise the effects can't be seen when rendering.- You can now set the
ArcadeWorld.fixedStepproperty via theArcadeWorldConfigobject (thanks @samme) Utils.Array.NumerArraycan now accept thestartandendparameters in reverse order, i.e.10, 1will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.DataManager.Events.DESTROYis a new event that the Data Manager will listen for from its parent and then call its owndestroymethod when received.- The
Quaternionclass constructor will now default the values to0,0,0,1if they're not provided, making it an identity quaternion, rather than the0,0,0,0it was before. - You can now set the
ParticleEmitter.reservevalue via the emitter configuration object (thanks @vforsh) - Setting the
pixelArtconfig option will now setantialiasGLtofalse, as well asantialias. Fix #5309 (thanks @Vegita2) - The
Shapeclass now includes theComputedSizecomponent properties and methods directly in the class, rather than applying as a mixin.setSizeis now flagged as beingprivate, 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.maxParallelDownloadsvalue is now set to 6 if running on Android, or 32 on any other OS. This avoidsnet::ERR_FAILEDissues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary) WebGLRenderer.defaultScissoris a new property that holds the default scissor dimensions for the renderer. This is modified duringresizeand avoids continuous array generation in thepreRenderloop.- When running an Arcade Physics
overlaptest against aStaticBody, it will no longer set theblockedstates 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
LineGame 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
Quaternionclass now has 4 new private properties:_x,_y,_zand_wand 4 new getters and setters for the public versions. It also now passes most methods viasetto allow for the onChange callback to be invoked. This does not change the public-facing API. Groupnow extendsEventEmitter, allowing you to emit custom events from within a Group.Device.Audio.wavnow usesaudio/wavas thecanPlayTypecheck string, instead ofaudio/wav; codecs="1", which should allow iOS13 to play wav files again.- In the
Loader.FileTypes.TextFileconfig you can now override the type and cache destination for the file. Loader.MultiFilewill 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 fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.RenderTexture.fillwould 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
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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
ProcessQueuewas emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar) - The
GridAlignaction didn't work if only theheightparameter was set. Fix #5019 (thanks @halilcakar) - The
Color.HSVToRGBfunction has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX) - Previously, the
easeParamsarray within a Tweenspropsobject, 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.setRenderToTextureitszoomandrotationvalues would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok) GameObjects.Shape.Gridwould render a white fill even if you passedundefinedas the fill color in the constructor. It now doesn't render cells if no fill color is given.- The
onMouseevents in the Input Manager didn't reset theactivePointerproperty 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
GetScreenOrientationfunction will now check forwindow.orientationfirst, 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 emitorientationchangeevents correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu) Time.Clock.addEventcan now take an instance of aTimerEventas its parameter. Fix #5294 (thanks @samme @EmilSV)GameConfig.audionow defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)- The
Loader.pathwas 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.getMatchingwould always return an empty array. It now returns matching children (thanks @samme)- The
ParticleManagerWebGLRenderernow 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
ParticleManagerCanvasRenderernow calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also usessetToContextinternally. 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
GraphicsWebGL Renderer will now default topathOpen = true. This fixes issues under WebGL where, for example, adding an arc and callingstrokePath, without first callingbeginPathwill no longer cause rendering artefacts when WebGL tries to close the path with a single tri. Graphics.strokeRoundedRectnow issuesmoveTocommands 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
snapshotin WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in theWebGLSnapshotfunction. Fix #4956 (thanks @gammafp @telinc1) - You can now draw a
Groupto aRenderTexture. 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.MoveTofunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.DOM.GetInnerHeightfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Bobclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsManagerclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsPluginclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Particles.EmitterOpclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.GetTextSizefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.MeasureTextfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.TextStylefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Input.CreatePixelPerfectHandlerfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapCircfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapRectfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Tilemapnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Componentsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.MatterGameObjectclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.PointerConstraintclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetPhysicsPluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetScenePluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Structs.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Tilemaps.Parsers.Tiledfunction has now been exposed on the Phaser namespace (thanks @samme) - Every single
Tilemap.Componentfunction 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:
TextureTintPipelineis now called theMultiPipeline.TextureTintStripPipelineis now called theRopePipeline.ForwardDiffuseLightPipelineis now called theLightPipeline.
To match the new pipeline names, the shader source code has also been renamed.
ForwardDiffuse.fragis now calledLight.frag.TextureTint.fragis now calledMulti.frag.TextureTint.vertis now calledMulti.vert.
Other pipeline changes are as follows:
Types.Renderer.WebGL.WebGLPipelineConfigis a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.Types.Renderer.WebGL.WebGLPipelineAttributesConfigis 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
rendererproperty automatically, so it's no longer required in the config. - All pipelines will now work out the
glproperty automatically, so it's no longer required in the config. - All pipelines will now extract the
nameproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexCapacityproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexSizeproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexDataproperty from the config, allowing you to set it externally. - All pipelines will now extract the
attributesproperty from the config, allowing you to set it externally. - All pipelines will now extract the
topologyproperty from the config, allowing you to set it externally. - The
WebGLPipeline.shouldFlushmethod now accepts an optional parameteramount. If given, it will returntrueif 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.set1fwill set a 1f uniform based on the given name.WebGLPipeline.set2fwill set a 2f uniform based on the given name.WebGLPipeline.set3fwill set a 3f uniform based on the given name.WebGLPipeline.set4fwill set a 4f uniform based on the given name.WebGLPipeline.set1fvwill set a 1fv uniform based on the given name.WebGLPipeline.set2fvwill set a 2fv uniform based on the given name.WebGLPipeline.set3fvwill set a 3fv uniform based on the given name.WebGLPipeline.set4fvwill set a 4fv uniform based on the given name.WebGLPipeline.set1ivwill set a 1iv uniform based on the given name.WebGLPipeline.set2ivwill set a 2iv uniform based on the given name.WebGLPipeline.set3ivwill set a 3iv uniform based on the given name.WebGLPipeline.set4ivwill set a 4iv uniform based on the given name.WebGLPipeline.set1iwill set a 1i uniform based on the given name.WebGLPipeline.set2iwill set a 2i uniform based on the given name.WebGLPipeline.set3iwill set a 3i uniform based on the given name.WebGLPipeline.set4iwill set a 4i uniform based on the given name.WebGLPipeline.setMatrix2fvwill set a matrix 2fv uniform based on the given name.WebGLPipeline.setMatrix3fvwill set a matrix 3fv uniform based on the given name.WebGLPipeline.setMatrix4fvwill 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.setFloat1has been removed. Please useset1finstead.WebGLPipeline.setFloat2has been removed. Please useset2finstead.WebGLPipeline.setFloat3has been removed. Please useset3finstead.WebGLPipeline.setFloat4has been removed. Please useset4finstead.WebGLPipeline.setFloat1vhas been removed. Please useset1fvinstead.WebGLPipeline.setFloat2vhas been removed. Please useset2fvinstead.WebGLPipeline.setFloat3vhas been removed. Please useset3fvinstead.WebGLPipeline.setFloat4vhas been removed. Please useset4fvinstead.WebGLPipeline.setInt1has been removed. Please useset1iinstead.WebGLPipeline.setInt2has been removed. Please useset2iinstead.WebGLPipeline.setInt3has been removed. Please useset3iinstead.WebGLPipeline.setInt4has been removed. Please useset4iinstead.WebGLPipeline.setMatrix1has been removed. Please usesetMatrix2fvinstead.WebGLPipeline.setMatrix2has been removed. Please usesetMatrix3fvinstead.WebGLPipeline.setMatrix3has been removed. Please usesetMatrix4fvinstead.
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.pipelinesis no longer a plain object containing pipeline instances. It's now an instance of thePipelineManagerclass. This instance is created during the init and boot phase of the renderer.- The
WebGLRenderer.currentPipelineproperty no longer exists, instead usePipelineManager.current. - The
WebGLRenderer.previousPipelineproperty no longer exists, instead usePipelineManager.previous. - The
WebGLRenderer.hasPipelinemethod no longer exists, instead usePipelineManager.has. - The
WebGLRenderer.getPipelinemethod no longer exists, instead usePipelineManager.get. - The
WebGLRenderer.removePipelinemethod no longer exists, instead usePipelineManager.remove. - The
WebGLRenderer.addPipelinemethod no longer exists, instead usePipelineManager.add. - The
WebGLRenderer.setPipelinemethod no longer exists, instead usePipelineManager.set. - The
WebGLRenderer.rebindPipelinemethod no longer exists, instead usePipelineManager.rebind. - The
WebGLRenderer.clearPipelinemethod no longer exists, instead usePipelineManager.clear.
The Pipeline Manager also offers the following new features:
- The
PipelineManager.resizemethod automatically handles resize events across all pipelines. - The
PipelineManager.preRendermethod calls the pre-render method of all pipelines. - The
PipelineManager.rendermethod calls the render method of all pipelines. - The
PipelineManager.postRendermethod calls the post-render method of all pipelines. - The
PipelineManager.setMultimethod automatically binds the Multi Texture Pipeline, Phaser's default. - The
PipelineManager.clearmethod will clear the pipeline, store it inpreviousand free the renderer. - The
PipelineManager.rebindmethod will reset the rendering context and restore thepreviouspipeline, if set.
New constants have been created to help you reference a pipeline without needing to use strings:
Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINEfor the Bitmap Mask Pipeline.Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINEfor the Light 2D Pipeline.Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINEfor the Single Pipeline.Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINEfor the Multi Pipeline.Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINEfor 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture that was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLPipeline.forceZerois a new property that informs Game Objects if the pipeline requires a zero bound texture unit.WebGLPipeline.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLRenderer.unbindTexturesis a new method that will activate and then null bind all WebGL textures.Renderer.WebGL.Utils.parseFragmentShaderMaxTexturesis 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis a new method that will look-up and return a normal map for the given object.
Lights
Light.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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.MVPis a new namespace under which the Model View Projection functions now live.projIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectIdentityprojPerspis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectPerspectivemodelRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateXmodelRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateYmodelRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateZviewLoadis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoadviewRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateXviewRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateYviewRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateZviewScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewScaleviewTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewTranslatemodelIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.IdentitymodelScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ScalemodelTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.TranslateviewIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewIdentityviewLoad2Dis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoad2DprojOrthois now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectOrthoPhaser.Renderer.WebGL.MVP.SetIdentityis a new function the others use, to save on space.
BitmapText - New Features, Updates and API Changes
BitmapText.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycoordinates. The character data includes the code, position, dimensions, and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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
setMaxWidthonDynamicBitmapText, 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_SCENEis 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_SCENEis 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_SCENEis 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_SCENEis 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.addedToSceneis 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.removedFromSceneis 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 theremovedFromScenemethod now. - The
Containerwill 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.eventsis a new property that references the Scene's Event Emitter. This is now used internally.DisplayList.addChildCallbackis a new method that overrides the List callback and fires the new ADDED events.DisplayList.removeChildCallbackis a new method that overrides the List callback and fires the new REMOVED events.GameObjectCreator.eventsis a new property that references the Scene's Event Emitter. This is now used internally.GameObjectFactory.eventsis a new property that references the Scene's Event Emitter. This is now used internally.ProcessQueue.checkQueueis a new boolean property that will make sure only unique objects are added to the Process Queue.- The
Update Listnow uses the newcheckQueueproperty to ensure no duplicate objects are on the active list. DOMElementFactory,ExternFactory,ParticleManagerFactor,RopeFactoryandSpriteFactoryall no longer add the objects to the Update List, this is now handled by the ADDED events instead.Sprite,Rope,ParticleEmitterManager,ExternandDOMElementnow all override theaddedToSceneandremovedFromScenecallbacks 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.
SpineContaineris a new Game Object available viathis.add.spineContainerto 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.runtimeswhich will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo intoplugins/spine/in order for this to work and then runnpm 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-zeroerror 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.setAnimationmethod will now use thetrackIndexparameter ifignoreIfPlayingis set and run the check against this track index. Fix #4842 (thanks @vinerz) - The
SpineFilewill 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
destroymethod 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.gameDestroyis a new method that is called if the Game instance emits adestroyevent. It removes the Spine Game Objects from the factory and disposes of the Spine scene renderer.SpineFilewill 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
Animationclass no longer extendsEventEmitter, 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_KEYevents have been removed. Instead, please use the new events which all carry theframeKeyparameter, which can be used to handle frame specific events. The only exception to this isANIMATION_COMPLETE_KEY, which is a key specific version of the completion event. ANIMATION_UPDATE_EVENTis a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.ANIMATION_STOP_EVENTis a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of thestopmethods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)- The Game Object
Component.Animationcomponent has been renamed toAnimationStateand has moved namespace. It's now inPhaser.Animationsinstead ofGameObjects.Componentsto help differentiate it from theAnimationclass when browsing the documentation. - The
play,playReverse,playAfterDelay,playAfterRepeatandchainSprite and Animation Component methods can now all take aPhaser.Types.Animations.PlayAnimationConfigconfiguration object, as well as a string, as thekeyparameter. 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.createis 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,playAfterDelayandplayAfterRepeatwill 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.skipMissedFramesis 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.addMixis 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.getMixis a new method that will return the mix duration between the two given animations.AnimationManager.removeMixis a new method that will remove the mixture between either two animations, or all mixtures for the given animation.AnimationState.removeis a new method that will remove a locally stored Animation instance from a Sprite.AnimationState.getis a new method that will return a locally stored Animation instance from the Sprite.AnimationState.existsis a new method that will check if a locally stored Animation exists on the Sprite.- The internal
AnimationState.removemethod has been renamed toglobalRemove. AnimationState.textureManageris a new property that references the global Texture Manager.AnimationState.animsis a new property that contains locally created Animations in a Custom Map.AnimationState.playandSprite.playno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.AnimationState.playReverseandSprite.playReverseno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.- The
AnimationState.delayedPlaymethod has been renamed toplayAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration. - The
AnimationState.stopOnRepeatmethod has been renamed tostopAfterRepeat - The
AnimationState.getCurrentKeymethod has been renamed togetName. AnimationState.getFrameNameis a new method that will return the key of the current Animation Frame, if an animation has been loaded.AnimationState.playAfterDelayandSprite.playAfterDelayare new methods that will play the given animation after the delay in ms expires.AnimationState.playAfterRepeatandSprite.playAfterRepeatare 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.chainmethod is now available on the Sprite class. - The
AnimationState.stopAfterDelaymethod is now available on the Sprite class. - The
AnimationState.stopAfterRepeatmethod is now available on the Sprite class. - The
AnimationState.stopOnFramemethod is now available on the Sprite class. AnimationManager.createFromAsepriteis 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.AnimationStatenow 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 optionalPlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.- The
PlayAnimationConfig.frameRateproperty lets you optionally override the animation frame rate. - The
PlayAnimationConfig.durationproperty lets you optionally override the animation duration. - The
PlayAnimationConfig.delayproperty lets you optionally override the animation delay. - The
PlayAnimationConfig.repeatproperty lets you optionally override the animation repeat counter. - The
PlayAnimationConfig.repeatDelayproperty lets you optionally override the animation repeat delay value. - The
PlayAnimationConfig.yoyoproperty lets you optionally override the animation yoyo boolean. - The
PlayAnimationConfig.showOnStartproperty lets you optionally override the animation show on start value. - The
PlayAnimationConfig.hideOnCompleteproperty lets you optionally override the animation hide on complete value. - The
PlayAnimationConfig.startFrameproperty lets you optionally set the animation frame to start on. - The
PlayAnimationConfig.timeScaleproperty lets you optionally set the animation time scale factor. AnimationState.delayCounteris a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animationSTARTevents fire. Fix #4426 (thanks @bdaenen)AnimationState.hasStartedis 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.showOnStartis a new boolean property that controls if the Game Object should havesetVisible(true)called on it when the animation starts.AnimationState.hideOnCompleteis a new boolean property that controls if the Game Object should havesetVisible(false)called on it when the animation completes.- The
AnimationState.chainmethod docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does! - The
AnimationState.setDelaymethod has been removed. It never actually worked and you can now perform the same thing by calling eitherplayAfterDelayor setting thedelayproperty in the play config. - The
AnimationState.getDelaymethod has been removed. You can now read thedelayproperty directly. - The
AnimationState.setRepeatmethod has been removed. You can achieve the same thing by setting therepeatproperty in the play config, or adjusting the publicrepeatCounterproperty if the animation has started. AnimationState.handleStartis a new internal private method that handles the animation start process.AnimationState.handleRepeatis a new internal private method that handles the animation repeat process.AnimationState.handleStopis a new internal private method that handles the animation stop process.AnimationState.handleCompleteis a new internal private method that handles the animation complete process.AnimationState.emitEventsis a new internal private method that emits animation events, cutting down on duplicate code.- The
AnimationState.restartmethod has a new optional boolean parameterresetRepeatswhich controls if you want to reset the repeat counter during the restart, or not. Animation.getTotalFramesis a new method that will return the total number of frames in the animation. You can access it viathis.anims.currentAnim.getTotalFramesfrom a Sprite.Animation.calculateDurationis a new method that calculates the duration, frameRate and msPerFrame for a given animation target.- The
BuildGameObjectAnimationfunction now uses thePlayAnimationConfigobject to set the values. Sprite.playReverseis a new method that allows you to play the given animation in reverse on the Sprite.Sprite.playAfterDelayis a new method that allows you to play the given animation on the Sprite after a delay.Sprite.stopis a new method that allows you to stop the current animation on the Sprite.AnimationManager.loadhas been removed as it's no longer required.AnimationManager.staggerPlayhas been fixed so you can now pass in negative stagger values.AnimationManager.staggerPlayhas a new optional boolean parameterstaggerFirst, which allows you to either include or exclude the first child in the stagger calculations.- The
Animation.completeAnimationmethod has been removed as it's no longer required. - The
Animation.loadmethod has been removed as it's no longer required. - The
Animation.setFramemethod has been removed as it's no longer required. - The
Animation.getFirstTickmethod has no longer needs theincludeDelayparameter, as it's handled byAnimationStatenow. - The
Animation.getFramesmethod has a new optional boolean parametersortFrameswhich will run a numeric sort on the frame names after constructing them, if a string-based frame is given. Types.Animations.Animationhas a new boolean propertysortFrames, which lets Phaser numerically sort the generated frames.AnimationState.timeScaleis a new public property that replaces the old private_timeScaleproperty.AnimationState.delayis a new public property that replaces the old private_delayproperty.AnimationState.repeatis a new public property that replaces the old private_repeatproperty.AnimationState.repeatDelayis a new public property that replaces the old private_repeatDelayproperty.AnimationState.yoyois a new public property that replaces the old private_yoyoproperty.AnimationState.inReverseis a new public property that replaces the old private_reverseproperty.AnimationState.startAnimationis a new public method that replaces the old private_startAnimationmethod.- The
AnimationState.getProgressmethod has been fixed so it will return correctly if the animation is playing in reverse. - The
AnimationState.globalRemovemethod will now always be called when an animation is removed from the global Animation Manager, not just once. - The
AnimationState.getRepeatmethod has now been removed. You can get the value from therepeatproperty. - The
AnimationState.setRepeatDelaymethod has now been removed. You can set the value using therepeatDelayconfig property, or changing it at run-time. AnimationState.completeis a new method that handles the completion in animation playback.- The
AnimationState.setTimeScalemethod has now been removed. You can set the value using thetimeScaleconfig property, or changing it at run-time. - The
AnimationState.getTimeScalemethod has now been removed. You can read the value using thetimeScaleproperty. - The
AnimationState.getTotalFramesmethod has been fixed and won't error if called when no animation is loaded. - The
AnimationState.setYoyomethod has now been removed. You can set the value using theyoyoconfig property, or changing it at run-time. - The
AnimationState.getYoyomethod has now been removed. You can read the value using theyoyoproperty. - The
AnimationState.stopAfterRepeatmethod now has an optional parameterrepeatCount, 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.updateFramemethod has now been removed. Everything is handled bysetCurrentFrameinstead, which removes one extra step out of the update process. GenerateFrameNameswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswould 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.GenerateFrameNumberscan now accept thestartandendparameters in reverse order, meaning you can now do{ start: 10, end: 1 }to create the animation in reverse.GenerateFrameNamescan now accept thestartandendparameters 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.refreshis now called when theGame.READYevent 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
inputMouseCapturehas been removed, as this is now split into 3 new config options: inputMousePreventDefaultDownis a new config option that allows you to controlpreventDefaultcalls specifically on mouse down events. Set it viainput.mouse.preventDefaultDownin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultUpis a new config option that allows you to controlpreventDefaultcalls specifically on mouse up events. Set it viainput.mouse.preventDefaultUpin the Game Config. It defaults totrue, the same as the previouscaptureproperty did.inputMousePreventDefaultMoveis a new config option that allows you to controlpreventDefaultcalls specifically on mouse move events. Set it viainput.mouse.preventDefaultMovein the Game Config. It defaults totrue, the same as the previouscaptureproperty did.- The
MouseManager.captureproperty has been removed, as this is now split into 3 new config options (see below) MouseManager.preventDefaultDownis a new boolean property, set via theinputMousePreventDefaultDownconfig option that allows you to toggle capture of mouse down events at runtime.MouseManager.preventDefaultUpis a new boolean property, set via theinputMousePreventDefaultUpconfig option that allows you to toggle capture of mouse up events at runtime.MouseManager.preventDefaultMoveis a new boolean property, set via theinputMousePreventDefaultMoveconfig option that allows you to toggle capture of mouse move events at runtime.- In the
MouseManagerthe 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
GamepadPluginwill now callrefreshPadsas 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 viathis.input.gamepad.pad1and 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._createdis 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.downwill 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
useHandCursorenabled, 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.shutdownmethod 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.tintTopLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTLwhich has now been removed.Tint.tintTopRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintTRwhich has now been removed.Tint.tintBottomLeftis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBLwhich has now been removed.Tint.tintBottomRightis now a normal property in RGB order, not a setter, and no longer passes through theGetColorFromValuefunction. This directly replaces the private property_tintBRwhich has now been removed.- The property
Tint._isTintedhas been removed as it's no longer required. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they now read the color value asoutTint.bgrinstead ofoutTint.rgb. This allows the colors to remain in RGB order within the Tint component. - The
Single.frag,Light.fragandMulti.fragshaders have all been updated so they no longer have a 3-way check on theoutTintEffectvalue. - The
Multi Pipeline,Bitmap Text,Render Texture,Text,TileSpriteandCameranow all read the tint values from the public properties instead of the private_tintTLetc ones. They also now set thetintEffectvalue directly from thetintFillproperty, removing another conditional check. - The function
GetColorFromValuehas been removed as it's no longer used internally. - The
Rope.tintFillproperty is now a boolean, not an integer, and can no longer take2as 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
getTintAppendFloatAlphaAndSwaphave been replaced withgetTintAppendFloatAlphainstead. - As a result of the change to the shader, the Multi Pipeline now uses the
WebGLRenderer.whiteTextureandtintEffectmode 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.whiteTextureis 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
TextureManagernow generates a new texture with the key__WHITEdurings its boot process. This is a pure white 4x4 texture used by the Graphics pipelines. Config.images.whiteis 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
Bodyclass has a new boolean propertypushable(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.setPushableis a new chainable method that allows you to set thepushablestate of a Body.Arcade.Components.Pushableis 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.disableUpdateis a new method that will prevent the Arcade Physics Worldupdatemethod 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.enableUpdateis 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.customUpdateis a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. Iftruethe World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)Physics.Arcade.Body.setCollideWorldBoundsnow has a new optional parameteronWorldBoundswhich allows you to enable the Body'sonWorldBoundsproperty in the same call (thanks @samme)ArcadePhysics.Body.setMaxVelocityXis a new method that allows you to set the maximum horizontal velocity of a Body (thanks @samme)ArcadePhysics.Body.setMaxVelocityYis a new method that allows you to set the maximum vertical velocity of a Body (thanks @samme)- The
PhysicsGroupconfig now has two new optional propertiesmaxVelocityXandmaxVelocityYwhich allows you to set the maximum velocity on bodies added to the Group (thanks @samme) - The
Arcade.Body.resetFlagsmethod has a new optional boolean parameterclear. If set, it clears thewasTouchingflags on the Body. This happens automatically whenBody.resetis called. Previous to this, the flags were not reset until the next physics step (thanks @samme) Physics.Arcade.ProcessXis a new set of functions, called by theSeparateXfunction, that handles all of the different collision tests, checks and resolutions. These functions are not exposed in the public API.Physics.Arcade.ProcessYis a new set of functions, called by theSeparateYfunction, 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.
AtlasJSONFileno longer stores the JSON in the JSON Cache once the texture has been created.AtlasXMLFileno longer stores the XML in the XML Cache once the texture has been created.UnityAtlasFileno longer stores the Text in the Text Cache once the texture has been created.BitmapFontFileno longer stores the XML in the XML Cache once the texture has been created.- You can now use
TextureManager.removeto 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#RESIZEevent no longer sends theresolutionas a parameter. - The
BaseCamera.resolutionproperty has been removed. - The internal private
BaseCamera._cx,_cy,_cwand_chproperties has been removed, usex,y,widthandheightinstead. - The
BaseCamera.preRendermethod no longer receives or uses theresolutionparameter. - The
Camera.preRendermethod no longer receives or uses theresolutionparameter. - The
CameraManager.onResizemethod no longer receives or uses theresolutionparameter. - The
Core.Config.resolutionproperty has been removed. - The
TextStyle.resolutionproperty 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
CanvasRendererno longer reads or uses the Game Config resolution property. - The
PipelineManager.resizemethod along withWebGLPipeline.resizeand anything else that extends them no longer receives or uses theresolutionparameter. - The
WebGLRenderer.resizeandonResizemethods no longer receives or uses theresolutionparameter. - The
ScaleManager.resolutionproperty 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.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Intersects.GetLineToPointsis 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.GetRaysFromPointToPolygonis 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.Translateis a new function that allows you to translate all the points of a polygon by the given values.Geom.Polygon.Simplifyis 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.setInt1ivwill allow you to look-up and set a 1iv uniform on the given shader.Phaser.Types.Math.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.getTweensOfhas a new parameterincludePending. 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.hasBootedis 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 theWebGLRenderer.addPipelinemethod, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)- The WebGL Renderer will now add the pipelines during the
bootmethod, instead ofinit. - You can now use
this.rendererfrom within a Scene, as it's now a Scene-level property and part of the Injection Map. Clock.addEventcan now take an existingTimerEventobject, as well as a config object. If aTimerEventis 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.removeEventis a new method that allows you to remove aTimerEvent, or an array of them, from all internal lists of the current Clock.Group.getMatchingis a new method that will return any members of the Group that match the given criteria, such asgetMatching('visible', true)(thanks @atursams)Utils.Array.SortByDigitsis 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 callingGroup.createMultipleorGroup.createFromConfig, can now accept the following new properties:setOrigin: { x, y, stepX, stepY }which are applied to the items created by the Group.Transform.copyPositionis a new method that will copy the position from the given object to the Game Object (thanks @samme)- The
Text.MeasureTextfunction, 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 newactualBoundingBoxAscentfunctions 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.GetCalcMatrixis 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,StarandTriangle. This dramatically reduces the amount of duplicate code across the API.Utils.Array.Matrix.Translateis a new function that will translate an Array Matrix by horizontally and vertically by the given amounts.Vertor3.addScaleis 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
easeParamsin the config object, allowing you to pass custom ease parameters through to an ease function (thanks @vforsh) BitmapMask.createMaskis 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.clearMaskwill 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.Quaternionnow has a new propertyonChangeCallbackwhich, if set, will be invoked each time the quaternion is updated. This allows you to link change events to other objects.- The
Quaternion.setmethod has a new optional boolean parameterupdate(defaults totrue), which will call theonChangeCallbackif set. Quaternion.setFromEuleris a new method that will set the quaternion from the givenEulerobject, optionally calling theonChangeCallbackin the process.Quaternion.setFromRotationMatrixis a new method that will set the rotation of the quaternion from the given Matrix4.Vector3.setFromMatrixPositionis a new method that will set the components of the Vector3 based on the position of the given Matrix4.Vector3.setFromMatrixColumnis a new method that will set the components of the Vector3 based on the specified Matrix4 column.Vector3.fromArrayis a new method that will set the components of the Vector3 based on the values in the given array, at the given offset.Vector3.minis a new method that will set the components of the Vector3 based on theMain.minbetween it and the given Vector3.Vector3.maxis a new method that will set the components of the Vector3 based on theMain.maxbetween it and the given Vector3.Vector3.addVectorsis a new method that will set the components of the Vector3 based on the addition of the two Vector3s given.Vector3.addScalaris a new method that will multiply the components of the Vector3 by the scale value given.Vector3.applyMatrix3is a new method that will take a Matrix3 and apply it to the Vector3.Vector3.applyMatrix4is a new method that will take a Matrix4 and apply it to the Vector3.Vector3.projectViewMatrixis a new method that multiplies the Vector3 by the given view and projection matrices.Vector3.unprojectViewMatrixis a new method that multiplies the Vector3 by the given inversed projection matrix and world matrix.Matrix4.getMaxScaleOnAxisis a new method that will return the maximum axis scale from the Matrix4.Matrix4.lookAtRHis a new method that will generate a right-handed look-at matrix from the given eye, target and up positions.Matrix4.transformis a new method that will generate a transform matrix from the given position and scale vectors and a rotation quaternion.Matrix4.multiplyMatricesis a new method that multiplies two given Matrix4 objects and stores the results in the Matrix4.Matrix4.premultiplyis a new method that takes a Matrix4 and multiplies it by the current Matrix4.Matrix4.getInverseis a new method that takes a Matrix4, copies it to the current matrix, then returns the inverse of it.WebGLRenderer.instancedArraysExtensionis a new property that holds the WebGL Extension for instanced array drawing, if supported by the browser.WebGLRenderer.vaoExtensionis 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.Earcutand is fully documented. Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.- The
TextureTintStripPipelinenow extendsTextureTintPipelineand just changes the topolgy, vastly reducing the filesize. TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself. - The constant
Phaser.Renderer.WebGL.BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.FLOATvalue has been removed as it wasn't used internally. global.Phaser = Phaserhas 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.downTimenow 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.upTimenow 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.getDurationmethod now uses the new PointerdownTimeandupTimevalues, 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
BaseShaderdefault vertex shader now includes theoutTexCoordvec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok) - When using the
GameObjectCreatorforContainersyou can now specify thechildrenproperty in the configuration object. WebGLRenderer.finalTypeis a new boolean property that signifies if the current Game Object being rendered is the final one in the list.- The
WebGLRenderer.updateCanvasTexturemethod will now setgl.UNPACK_PREMULTIPLY_ALPHA_WEBGLto 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.JSONHashwill now perform ahasOwnPropertycheck when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes fromJSON.parse. Fix #4768 (thanks @RollinSafary)- The
Camera3DPlugin 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.seekwill 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.previousPipelineis a new property that is set during a call toclearPipelineand used during calls torebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.- The
WebGLRenderer.rebindPipelinemethod has been changed slightly. Previously, you had to specify thepipelineInstance, but this is now optional. If you don't, it will use the newpreviousPipelineproperty instead. If not set, or none given, it will now return without throwing gl errors as well. - If
inputWindowEventsis set in the Game Config, then theMouseManagerwill now listen for the events onwindow.topinstead of justwindow, which should help in situations where the pointer is released outside of an embedded iframe. Fix #4824 (thanks @rexrainbow) Types.GameObjects.Text.GetTextSizeObjectis a new type def for the GetTextSize function results.Utils.Array.StableSorthas 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. Theinplacefunction has been removed, just callStableSort(array)directly now. All classes that usedStableSort.inplacehave 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.setOriginwill now callupdateDisplayOriginon the items array, otherwise the effects can't be seen when rendering.- You can now set the
ArcadeWorld.fixedStepproperty via theArcadeWorldConfigobject (thanks @samme) Utils.Array.NumerArraycan now accept thestartandendparameters in reverse order, i.e.10, 1will generate a number array running from 10 to 1. Internally it has also been optimized to skip string based returns.DataManager.Events.DESTROYis a new event that the Data Manager will listen for from its parent and then call its owndestroymethod when received.- The
Quaternionclass constructor will now default the values to0,0,0,1if they're not provided, making it an identity quaternion, rather than the0,0,0,0it was before. - You can now set the
ParticleEmitter.reservevalue via the emitter configuration object (thanks @vforsh) - Setting the
pixelArtconfig option will now setantialiasGLtofalse, as well asantialias. Fix #5309 (thanks @Vegita2) - The
Shapeclass now includes theComputedSizecomponent properties and methods directly in the class, rather than applying as a mixin.setSizeis now flagged as beingprivate, 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.maxParallelDownloadsvalue is now set to 6 if running on Android, or 32 on any other OS. This avoidsnet::ERR_FAILEDissues specifically on Android. You can still override this in the Game Config if you wish. Fix #4957 (thanks @RollinSafary) WebGLRenderer.defaultScissoris a new property that holds the default scissor dimensions for the renderer. This is modified duringresizeand avoids continuous array generation in thepreRenderloop.- When running an Arcade Physics
overlaptest against aStaticBody, it will no longer set theblockedstates 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
LineGame 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
Quaternionclass now has 4 new private properties:_x,_y,_zand_wand 4 new getters and setters for the public versions. It also now passes most methods viasetto allow for the onChange callback to be invoked. This does not change the public-facing API.
Bug Fixes
RenderTexture.resize(which is called fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.RenderTexture.fillwould 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
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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
ProcessQueuewas emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar) - The
GridAlignaction didn't work if only theheightparameter was set. Fix #5019 (thanks @halilcakar) - The
Color.HSVToRGBfunction has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX) - Previously, the
easeParamsarray within a Tweenspropsobject, 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.setRenderToTextureitszoomandrotationvalues would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok) GameObjects.Shape.Gridwould render a white fill even if you passedundefinedas the fill color in the constructor. It now doesn't render cells if no fill color is given.- The
onMouseevents in the Input Manager didn't reset theactivePointerproperty 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
GetScreenOrientationfunction will now check forwindow.orientationfirst, 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 emitorientationchangeevents correctly on iOS. Fix #4361 #4914 (thanks @pfdtravalmatic @jackfreak @cuihu) Time.Clock.addEventcan now take an instance of aTimerEventas its parameter. Fix #5294 (thanks @samme @EmilSV)GameConfig.audionow defaults to an empty object, which simplifies access to the config in later checks (thanks @samme)- The
Loader.pathwas 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.getMatchingwould always return an empty array. It now returns matching children (thanks @samme)- The
ParticleManagerWebGLRenderernow 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
ParticleManagerCanvasRenderernow calculates its transform matrix differently, splitting out the parent matrix and factoring in the follow offsets separately. It also usessetToContextinternally. 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
GraphicsWebGL Renderer will now default topathOpen = true. This fixes issues under WebGL where, for example, adding an arc and callingstrokePath, without first callingbeginPathwill no longer cause rendering artefacts when WebGL tries to close the path with a single tri. Graphics.strokeRoundedRectnow issuesmoveTocommands 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
snapshotin WebGL it would often have an extra line of empty pixels at the top of the resulting image, due to a rounding error in theWebGLSnapshotfunction. Fix #4956 (thanks @gammafp @telinc1) - You can now draw a
Groupto aRenderTexture. 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.MoveTofunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.DOM.GetInnerHeightfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Bobclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsManagerclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsPluginclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Particles.EmitterOpclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.GetTextSizefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.MeasureTextfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.TextStylefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Input.CreatePixelPerfectHandlerfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapCircfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapRectfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Tilemapnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Componentsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.MatterGameObjectclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.PointerConstraintclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetPhysicsPluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetScenePluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Structs.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Tilemaps.Parsers.Tiledfunction has now been exposed on the Phaser namespace (thanks @samme) - Every single
Tilemap.Componentfunction 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:
TextureTintPipelineis now called theMultiPipeline.TextureTintStripPipelineis now called theRopePipeline.ForwardDiffuseLightPipelineis now called theLightPipeline.
To match the new pipeline names, the shader source code has also been renamed.
ForwardDiffuse.fragis now calledLight.frag.TextureTint.fragis now calledMulti.frag.TextureTint.vertis now calledMulti.vert.
Other pipeline changes are as follows:
Types.Renderer.WebGL.WebGLPipelineConfigis a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.Types.Renderer.WebGL.WebGLPipelineAttributesConfigis 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
rendererproperty automatically, so it's no longer required in the config. - All pipelines will now work out the
glproperty automatically, so it's no longer required in the config. - All pipelines will now extract the
nameproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexCapacityproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexSizeproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexDataproperty from the config, allowing you to set it externally. - All pipelines will now extract the
attributesproperty from the config, allowing you to set it externally. - All pipelines will now extract the
topologyproperty 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture that was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLPipeline.forceZerois a new property that informs Game Objects if the pipeline requires a zero bound texture unit.WebGLPipeline.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLRenderer.unbindTexturesis a new method that will activate and then null bind all WebGL textures.Renderer.WebGL.Utils.parseFragmentShaderMaxTexturesis 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis a new method that will look-up and return a normal map for the given object.
Lights
Light.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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.MVPis a new namespace under which the Model View Projection functions now live.projIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectIdentityprojPerspis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectPerspectivemodelRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateXmodelRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateYmodelRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateZviewLoadis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoadviewRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateXviewRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateYviewRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateZviewScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewScaleviewTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewTranslatemodelIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.IdentitymodelScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ScalemodelTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.TranslateviewIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewIdentityviewLoad2Dis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoad2DprojOrthois now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectOrthoPhaser.Renderer.WebGL.MVP.SetIdentityis a new function the others use, to save on space.
BitmapText New Features, Updates and API Changes
BitmapText.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycoordinates. The character data includes the code, position, dimensions, and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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_SCENEis 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_SCENEis 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_SCENEis 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_SCENEis 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.addedToSceneis 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.removedFromSceneis 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 theremovedFromScenemethod now. - The
Containerwill 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.eventsis a new property that references the Scene's Event Emitter. This is now used internally.DisplayList.addChildCallbackis a new method that overrides the List callback and fires the new ADDED events.DisplayList.removeChildCallbackis a new method that overrides the List callback and fires the new REMOVED events.GameObjectCreator.eventsis a new property that references the Scene's Event Emitter. This is now used internally.GameObjectFactory.eventsis a new property that references the Scene's Event Emitter. This is now used internally.ProcessQueue.checkQueueis a new boolean property that will make sure only unique objects are added to the Process Queue.- The
Update Listnow uses the newcheckQueueproperty to ensure no duplicate objects are on the active list. DOMElementFactory,ExternFactory,ParticleManagerFactor,RopeFactoryandSpriteFactoryall no longer add the objects to the Update List, this is now handled by the ADDED events instead.Sprite,Rope,ParticleEmitterManager,ExternandDOMElementnow all override theaddedToSceneandremovedFromScenecallbacks 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.
SpineContaineris a new Game Object available viathis.add.spineContainerto 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.runtimeswhich will build all of the Spine runtimes, for ingestion by the plugin. Note: You will need to check-out the Esoteric Spine Runtimes repo intoplugins/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-zeroerror 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.setAnimationmethod will now use thetrackIndexparameter ifignoreIfPlayingis set and run the check against this track index. Fix #4842 (thanks @vinerz) - The
SpineFilewill 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
destroymethod 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.gameDestroyis a new method that is called if the Game instance emits adestroyevent. 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
Animationclass no longer extendsEventEmitter, 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_KEYevents have been removed. Instead, please use the new events which all carry theframeKeyparameter, which can be used to handle frame specific events. ANIMATION_UPDATE_EVENTis a new event that is emitted from a Sprite when an animation updates, i.e. its frame changes.ANIMATION_STOP_EVENTis a new event that is emitted from a Sprite when its current animation is stopped. This can happen if any of thestopmethods are called, or a new animation is played prior to this one reaching completion. Fix #4894 (thanks @scott20145)- The Game Object
Component.Animationcomponent has been renamed toAnimationStateand has moved namespace. It's now inPhaser.Animationsinstead ofGameObjects.Componentsto help differentiate it from theAnimationclass when browsing the documentation. - The
play,playReverse,playAfterDelay,playAfterRepeatandchainSprite and Animation Component methods can now all take aPhaser.Types.Animations.PlayAnimationConfigconfiguration object, as well as a string, as thekeyparameter. 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.createis 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,playAfterDelayandplayAfterRepeatwill 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.skipMissedFramesis 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.addMixis 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.getMixis a new method that will return the mix duration between the two given animations.AnimationManager.removeMixis a new method that will remove the mixture between either two animations, or all mixtures for the given animation.AnimationState.removeis a new method that will remove a locally stored Animation instance from a Sprite.AnimationState.getis a new method that will return a locally stored Animation instance from the Sprite.AnimationState.existsis a new method that will check if a locally stored Animation exists on the Sprite.- The internal
AnimationState.removemethod has been renamed toglobalRemove. AnimationState.textureManageris a new property that references the global Texture Manager.AnimationState.animsis a new property that contains locally created Animations in a Custom Map.AnimationState.playandSprite.playno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.AnimationState.playReverseandSprite.playReverseno longer accept astartFrameparameter. Please set it via thePlayAnimationConfiginstead.- The
AnimationState.delayedPlaymethod has been renamed toplayAfterDelay. The parameter order has also changed, so the key now comes first instead of the duration. - The
AnimationState.stopOnRepeatmethod has been renamed tostopAfterRepeat - The
AnimationState.getCurrentKeymethod has been renamed togetName. AnimationState.getFrameNameis a new method that will return the key of the current Animation Frame, if an animation has been loaded.AnimationState.playAfterDelayandSprite.playAfterDelayare new methods that will play the given animation after the delay in ms expires.AnimationState.playAfterRepeatandSprite.playAfterRepeatare 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.chainmethod is now available on the Sprite class. - The
AnimationState.stopAfterDelaymethod is now available on the Sprite class. - The
AnimationState.stopAfterRepeatmethod is now available on the Sprite class. - The
AnimationState.stopOnFramemethod is now available on the Sprite class. AnimationManager.createFromAsepriteis 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.AnimationStatenow 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 optionalPlayAnimationConfig. This improves performance and massively reduces CPU calls in animation heavy games.- The
PlayAnimationConfig.frameRateproperty lets you optionally override the animation frame rate. - The
PlayAnimationConfig.durationproperty lets you optionally override the animation duration. - The
PlayAnimationConfig.delayproperty lets you optionally override the animation delay. - The
PlayAnimationConfig.repeatproperty lets you optionally override the animation repeat counter. - The
PlayAnimationConfig.repeatDelayproperty lets you optionally override the animation repeat delay value. - The
PlayAnimationConfig.yoyoproperty lets you optionally override the animation yoyo boolean. - The
PlayAnimationConfig.showOnStartproperty lets you optionally override the animation show on start value. - The
PlayAnimationConfig.hideOnCompleteproperty lets you optionally override the animation hide on complete value. - The
PlayAnimationConfig.startFrameproperty lets you optionally set the animation frame to start on. - The
PlayAnimationConfig.timeScaleproperty lets you optionally set the animation time scale factor. AnimationState.delayCounteris a new property that allows you to control the delay before an animation will start playing. Only once this delay has expired, will the animationSTARTevents fire. Fix #4426 (thanks @bdaenen)AnimationState.hasStartedis 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.showOnStartis a new boolean property that controls if the Game Object should havesetVisible(true)called on it when the animation starts.AnimationState.hideOnCompleteis a new boolean property that controls if the Game Object should havesetVisible(false)called on it when the animation completes.- The
AnimationState.chainmethod docs said it would remove all pending animations if called with no parameters. However, it didn't - and now does! - The
AnimationState.setDelaymethod has been removed. It never actually worked and you can now perform the same thing by calling eitherplayAfterDelayor setting thedelayproperty in the play config. - The
AnimationState.getDelaymethod has been removed. You can now read thedelayproperty directly. - The
AnimationState.setRepeatmethod has been removed. You can achieve the same thing by setting therepeatproperty in the play config, or adjusting the publicrepeatCounterproperty if the animation has started. AnimationState.handleStartis a new internal private method that handles the animation start process.AnimationState.handleRepeatis a new internal private method that handles the animation repeat process.AnimationState.handleStopis a new internal private method that handles the animation stop process.AnimationState.handleCompleteis a new internal private method that handles the animation complete process.AnimationState.emitEventsis a new internal private method that emits animation events, cutting down on duplicate code.- The
AnimationState.restartmethod has a new optional boolean parameterresetRepeatswhich controls if you want to reset the repeat counter during the restart, or not. Animation.getTotalFramesis a new method that will return the total number of frames in the animation. You can access it viathis.anims.currentAnim.getTotalFramesfrom a Sprite.Animation.calculateDurationis a new method that calculates the duration, frameRate and msPerFrame for a given animation target.- The
BuildGameObjectAnimationfunction now uses thePlayAnimationConfigobject to set the values. Sprite.playReverseis a new method that allows you to play the given animation in reverse on the Sprite.Sprite.playAfterDelayis a new method that allows you to play the given animation on the Sprite after a delay.Sprite.stopis a new method that allows you to stop the current animation on the Sprite.AnimationManager.loadhas been removed as it's no longer required.AnimationManager.staggerPlayhas been fixed so you can now pass in negative stagger values.AnimationManager.staggerPlayhas a new optional boolean parameterstaggerFirst, which allows you to either include or exclude the first child in the stagger calculations.- The
Animation.completeAnimationmethod has been removed as it's no longer required. - The
Animation.loadmethod has been removed as it's no longer required. - The
Animation.setFramemethod has been removed as it's no longer required. - The
Animation.getFirstTickmethod has no longer needs theincludeDelayparameter, as it's handled byAnimationStatenow. - The
Animation.getFramesmethod has a new optional boolean parametersortFrameswhich will run a numeric sort on the frame names after constructing them, if a string-based frame is given. Types.Animations.Animationhas a new boolean propertysortFrames, which lets Phaser numerically sort the generated frames.AnimationState.timeScaleis a new public property that replaces the old private_timeScaleproperty.AnimationState.delayis a new public property that replaces the old private_delayproperty.AnimationState.repeatis a new public property that replaces the old private_repeatproperty.AnimationState.repeatDelayis a new public property that replaces the old private_repeatDelayproperty.AnimationState.yoyois a new public property that replaces the old private_yoyoproperty.AnimationState.inReverseis a new public property that replaces the old private_reverseproperty.AnimationState.startAnimationis a new public method that replaces the old private_startAnimationmethod.- The
AnimationState.getProgressmethod has been fixed so it will return correctly if the animation is playing in reverse. - The
AnimationState.globalRemovemethod will now always be called when an animation is removed from the global Animation Manager, not just once. - The
AnimationState.getRepeatmethod has now been removed. You can get the value from therepeatproperty. - The
AnimationState.setRepeatDelaymethod has now been removed. You can set the value using therepeatDelayconfig property, or changing it at run-time. AnimationState.completeis a new method that handles the completion in animation playback.- The
AnimationState.setTimeScalemethod has now been removed. You can set the value using thetimeScaleconfig property, or changing it at run-time. - The
AnimationState.getTimeScalemethod has now been removed. You can read the value using thetimeScaleproperty. - The
AnimationState.getTotalFramesmethod has been fixed and won't error if called when no animation is loaded. - The
AnimationState.setYoyomethod has now been removed. You can set the value using theyoyoconfig property, or changing it at run-time. - The
AnimationState.getYoyomethod has now been removed. You can read the value using theyoyoproperty. - The
AnimationState.stopAfterRepeatmethod now has an optional parameterrepeatCount, 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.updateFramemethod has now been removed. Everything is handled bysetCurrentFrameinstead, which removes one extra step out of the update process. GenerateFrameNameswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswill nowconsole.warnif the generated frame isn't present in the texture, which should help with debugging animation creation massively.GenerateFrameNumberswould 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.GenerateFrameNumberscan now accept thestartandendparameters in reverse order, meaning you can now do{ start: 10, end: 1 }to create the animation in reverse.GenerateFrameNamescan now accept thestartandendparameters in reverse order, meaning you can now do{ start: 10, end: 1 }to create the animation in reverse.
New Features
Geom.Intersects.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Intersects.GetLineToPointsis 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.GetRaysFromPointToPolygonis 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.Translateis a new function that allows you to translate all the points of a polygon by the given values.Geom.Polygon.Simplifyis 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.setInt1ivwill allow you to look-up and set a 1iv uniform on the given shader.Phaser.Types.Math.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.getTweensOfhas a new parameterincludePending. 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.hasBootedis 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 theWebGLRenderer.addPipelinemethod, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)- The WebGL Renderer will now add the pipelines during the
bootmethod, instead ofinit. - You can now use
this.rendererfrom within a Scene, as it's now a Scene-level property and part of the Injection Map. Clock.addEventcan now take an existingTimerEventobject, as well as a config object. If aTimerEventis 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.removeEventis a new method that allows you to remove aTimerEvent, or an array of them, from all internal lists of the current Clock.Group.getMatchingis a new method that will return any members of the Group that match the given criteria, such asgetMatching('visible', true)(thanks @atursams)ArcadePhysics.disableUpdateis a new method that will prevent the Arcade Physics Worldupdatemethod 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.enableUpdateis 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.customUpdateis a new boolean property you can set in the Arcade Physics config object, either in the Scene or in the Game Config. Iftruethe World update will never be called, allowing you to call it yourself from your own component. Close #5190 (thanks @cfortuner)Utils.Array.SortByDigitsis 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 callingGroup.createMultipleorGroup.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.Earcutand is fully documented. Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.- The
TextureTintStripPipelinenow extendsTextureTintPipelineand just changes the topolgy, vastly reducing the filesize. TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself. - The constant
Phaser.Renderer.WebGL.BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.FLOATvalue has been removed as it wasn't used internally. global.Phaser = Phaserhas 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.downTimenow 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.upTimenow 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.getDurationmethod now uses the new PointerdownTimeandupTimevalues, 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
BaseShaderdefault vertex shader now includes theoutTexCoordvec2 varying, mapped to be the same as that found in the pipeline shaders. Fix #5120 (@pavel-shirobok) - When using the
GameObjectCreatorforContainersyou can now specify thechildrenproperty in the configuration object. WebGLRenderer.finalTypeis a new boolean property that signifies if the current Game Object being rendered is the final one in the list.- The
WebGLRenderer.updateCanvasTexturemethod will now setgl.UNPACK_PREMULTIPLY_ALPHA_WEBGLto 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.JSONHashwill now perform ahasOwnPropertycheck when iterating the frames, skipping anything that isn't a direct property. This should allow you to use generated atlas data that comes fromJSON.parse. Fix #4768 (thanks @RollinSafary)- The
Camera3DPlugin 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.seekwill 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.previousPipelineis a new property that is set during a call toclearPipelineand used during calls torebindPipeline, allowing the renderer to rebind any previous pipeline, not just the Multi Pipeline.- The
WebGLRenderer.rebindPipelinemethod has been changed slightly. Previously, you had to specify thepipelineInstance, but this is now optional. If you don't, it will use the newpreviousPipelineproperty instead. If not set, or none given, it will now return without throwing gl errors as well. - If
inputWindowEventsis set in the Game Config, then theMouseManagerwill now listen for the events onwindow.topinstead of justwindow, which should help in situations where the pointer is released outside of an embedded iframe. Fix #4824 (thanks @rexrainbow) Types.GameObjects.Text.GetTextSizeObjectis a new type def for the GetTextSize function results.- The
Arcade.Body.resetFlagsmethod has a new optional boolean parameterclear. If set, it clears thewasTouchingflags on the Body. This happens automatically whenBody.resetis called. Previous to this, the flags were not reset until the next physics step (thanks @samme) Utils.Array.StableSorthas 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. Theinplacefunction has been removed, just callStableSort(array)directly now. All classes that usedStableSort.inplacehave 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.setOriginwill now callupdateDisplayOriginon the items array, otherwise the effects can't be seen when rendering.- You can now set the
ArcadeWorld.fixedStepproperty via theArcadeWorldConfigobject (thanks @samme) Utils.Array.NumerArraycan now accept thestartandendparameters in reverse order, i.e.10, 1will 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.MoveTofunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.DOM.GetInnerHeightfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Bobclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsManagerclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.LightsPluginclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.Particles.EmitterOpclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.GetTextSizefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.MeasureTextfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.GameObjects.TextStylefunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Input.CreatePixelPerfectHandlerfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapCircfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Components.OverlapRectfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Arcade.Tilemapnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Componentsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.MatterGameObjectclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Physics.Matter.PointerConstraintclass has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetPhysicsPluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Scenes.GetScenePluginsfunction has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Structs.Eventsnamespace has now been exposed on the Phaser namespace (thanks @samme) - The
Phaser.Tilemaps.Parsers.Tiledfunction has now been exposed on the Phaser namespace (thanks @samme) - Every single
Tilemap.Componentfunction 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 fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.RenderTexture.fillwould 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
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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
ProcessQueuewas emitting the wrong events internally. It now emits 'add' and 'remove' correctly (thanks @halilcakar) - The
GridAlignaction didn't work if only theheightparameter was set. Fix #5019 (thanks @halilcakar) - The
Color.HSVToRGBfunction has been rewritten to use the HSL and HSV formula from Wikipedia, giving much better results. Fix #5089 (thanks @DiamondeX) - Previously, the
easeParamsarray within a Tweenspropsobject, 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.setRenderToTextureitszoomandrotationvalues would be applied twice. Fix #4221 #4924 #4713 (thanks @wayfu @DanMcgraw @pavel-shirobok) GameObjects.Shape.Gridwould render a white fill even if you passedundefinedas 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:
TextureTintPipelineis now called theMultiPipeline.TextureTintStripPipelineis now called theRopePipeline.ForwardDiffuseLightPipelineis now called theLightPipeline.
To match the new pipeline names, the shader source code has also been renamed.
ForwardDiffuse.fragis now calledLight.frag.TextureTint.fragis now calledMulti.frag.TextureTint.vertis now calledMulti.vert.
Other pipeline changes are as follows:
Types.Renderer.WebGL.WebGLPipelineConfigis a new TypeDef that helps you easily configure your own Custom Pipeline when using TypeScript and also provides better JSDocs.Types.Renderer.WebGL.WebGLPipelineAttributesConfigis 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
rendererproperty automatically, so it's no longer required in the config. - All pipelines will now work out the
glproperty automatically, so it's no longer required in the config. - All pipelines will now extract the
nameproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexCapacityproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexSizeproperty from the config, allowing you to set it externally. - All pipelines will now extract the
vertexDataproperty from the config, allowing you to set it externally. - All pipelines will now extract the
attributesproperty from the config, allowing you to set it externally. - All pipelines will now extract the
topologyproperty 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture that was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones, and resets the active texture counter.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLPipeline.forceZerois a new property that informs Game Objects if the pipeline requires a zero bound texture unit.WebGLPipeline.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLRenderer.unbindTexturesis a new method that will activate and then null bind all WebGL textures.Renderer.WebGL.Utils.parseFragmentShaderMaxTexturesis 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis a new method that will look-up and return a normal map for the given object.
Lights
Light.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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.MVPis a new namespace under which the Model View Projection functions now live.projIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectIdentityprojPerspis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectPerspectivemodelRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateXmodelRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateYmodelRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateZviewLoadis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoadviewRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateXviewRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateYviewRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateZviewScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewScaleviewTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewTranslatemodelIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.IdentitymodelScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ScalemodelTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.TranslateviewIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewIdentityviewLoad2Dis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoad2DprojOrthois now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectOrthoPhaser.Renderer.WebGL.MVP.SetIdentityis a new function the others use, to save on space.
BitmapText New Features, Updates and API Changes
BitmapText.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycoordinates. The character data includes the code, position, dimensions, and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Intersects.GetLineToPointsis 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.GetRaysFromPointToPolygonis 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.Translateis a new function that allows you to translate all the points of a polygon by the given values.Geom.Polygon.Simplifyis 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.setInt1ivwill allow you to look-up and set a 1iv uniform on the given shader.Phaser.Types.Math.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.getTweensOfhas a new parameterincludePending. 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.hasBootedis 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 theWebGLRenderer.addPipelinemethod, and if not set, the pipeline is booted. Fix #5251 #5255 (thanks @telinc1 @rexrainbow)- The WebGL Renderer will now add the pipelines during the
bootmethod, instead ofinit.
Updates and API Changes
- Earcut, used for polygon triangulation, has been updated from 2.1.4 to 2.2.2.
Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.- The
TextureTintStripPipelinenow extendsTextureTintPipelineand just changes the topolgy, vastly reducing the filesize. TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself. - The constant
Phaser.Renderer.WebGL.BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_BYTEvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.UNSIGNED_SHORTvalue has been removed as it wasn't used internally. - The constant
Phaser.Renderer.WebGL.FLOATvalue has been removed as it wasn't used internally.
Bug Fixes
RenderTexture.resize(which is called fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.RenderTexture.fillwould 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
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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
ProcessQueuewas 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture tha was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones and resets the active texture counter.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLPipeline.forceZerois a new property that informs Game Objects if the pipeline requires a zero bound texture unit.WebGLPipeline.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLRenderer.unbindTexturesis 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis a new method that will look-up and return a normal map for the given object.
Lights
Light.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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.MVPis a new namespace under which the Model View Projection functions now live.projIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectIdentityprojPerspis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectPerspectivemodelRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateXmodelRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateYmodelRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateZviewLoadis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoadviewRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateXviewRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateYviewRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateZviewScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewScaleviewTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewTranslatemodelIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.IdentitymodelScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ScalemodelTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.TranslateviewIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewIdentityviewLoad2Dis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoad2DprojOrthois now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectOrthoPhaser.Renderer.WebGL.MVP.SetIdentityis a new function the others use, to save on space.
BitmapText New Features, Updates and API Changes
BitmapText.setCharacterTintis 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.setWordTintis 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.setDropShadowis 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.BitmapTextWebGLRendererhas been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated byGetBitmapTextSize. 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.getCharacterAtis a new method that will return the character data from the BitmapText at the givenxandycorodinates. The character data includes the code, position, dimensions and glyph information.- The
BitmapTextSizeobject returned byBitmapText.getTextBoundshas a new property calledcharacterswhich 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. ParseXMLBitmapFontwill 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.ParseXMLBitmapFontwill 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,BitmapTextCharacterandBitmapTextLinesare three new type defs that are now part of theBitmapTextSizeconfig object, as returned bygetTextBounds. This improves the TypeScript defs and JS Docs for this object.- The signature of the
ParseXMLBitmapFontfunction has changed. Theframeparameter 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.getTextBoundsmethod 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
GetBitmapTextSizefunction usedMath.roundon the values, if theroundparameter wastrue, which didn't create integers. It now usesMath.ceilinstead to give integer results. - The
GetBitmapTextSizefunction has a new boolean parameterupdateOrigin, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations. BitmapText.preDestroyis a new method that will tidy-up all of the BitmapText data during object destruction.BitmapText.dropShadowXis a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowYis a new property that controls the vertical offset of the drop shadow on the Bitmap Text.BitmapText.dropShadowColoris a new property that sets the color of the Bitmap Text drop shadow.BitmapText.dropShadowAlphais a new property that sets the alpha of the Bitmap Text drop shadow.BatchCharis 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
colorvalue in theDynamicBitmapText.setDisplayCallbackwould 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
setSizeto 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) ParseXMLBitmapFonthas a new optional parametertexture. 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.setInt1ivwill allow you to look-up and set a 1iv uniform on the given shader.Geom.Intersects.GetLineToLineis a new function that will return a Vector3 containing the point of intersection between 2 line segments, with thezproperty holding the distance value.Geom.Intersects.GetLineToPolygonis a new function that checks for the closest point of intersection between a line segment and an array of polygons.Geom.Polygon.Translateis a new function that allows you to translate all the points of a polygon by the given values.Phaser.Types.Math.Vector3Likeis a new data type representing as Vector 3 like object.Phaser.Types.Math.Vector4Likeis a new data type representing as Vector 4 like object.Transform.getLocalPointis a new method, available on all Game Objects, that takes anx/ypair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.- The
KeyboardPluginwill 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.GetColorFromValueis 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.RemoveAtis a new function that will remove a character from the given index in a string and return the new string.Frame.setUVsis 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.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.- The
TextureTintStripPipelinenow extendsTextureTintPipelineand just changes the topolgy, vastly reducing the filesize. TransformMatrix.getXRoundis a new method that will return the X component, optionally passed viaMath.round.TransformMatrix.getYRoundis a new method that will return the Y component, optionally passed viaMath.round.- The
KeyboardPluginno longer emitskeydown_events. These were replaced withkeydown-events in v3.15. The previous event string was deprecated in v3.20. - The
KeyboardPluginno longer emitskeyup_events. These were replaced withkeyup-events in v3.15. The previous event string was deprecated in v3.20. - The
ScaleManager.updateBoundsmethod 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 theupdateBoundsmethod directly, yourself.
Bug Fixes
RenderTexture.resize(which is called fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.- The
MatterAttractorsplugin, 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
KeyboardManagerandKeyboardPluginwere both still checking for theInputManager.useQueueproperty, 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.maxTexturesis a new game config setting that allows you to control how many texture units will be used in WebGL.WebGL.Utils.checkShaderMaxis a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.- The property
WebGLRenderer.currentActiveTextureUnithas been renamed tocurrentActiveTexture. WebGLRenderer.startActiveTextureis a new read-only property contains the current starting active texture unit.WebGLRenderer.maxTexturesis a new read-only property that contains the maximum number of texture units WebGL can use.WebGLRenderer.textureIndexesis a new read-only array that contains all of the available WebGL texture units.WebGLRenderer.tempTexturesis a new read-only array that contains temporary WebGL textures.- The
WebGLRenderer.currentTexturesproperty has been removed, as it's no longer used. TextureSource.glIndexis a new property that holds the currently assigned texture unit for the Texture Source.TextureSource.glIndexCounteris a new property that holds the time the index was assigned to the Texture Source.WebGLRenderer.currentTextureshas been removed, as it's no longer used internally.WebGLRenderer.setBlankTextureno longer has aforceparameter, 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
inTexIdfloat attribute and dynamic generation. - The Texture Tint Pipeline has a new attribute,
inTexIdwhich is agl.FLOAT. TextureTintPipeline.bindis a new method that sets theuMainSampleruniform.- The
TextureTintPipeline.requireTextureBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.pushBatchmethod has been removed, as it's no longer required. - The
TextureTintPipeline.maxQuadsproperty has been removed, as it's no longer required. - The
TextureTintPipeline.batchesproperty has been removed, as it's no longer required. TextureTintPipeline.flushhas been rewritten to support multi-textures.TextureTintPipeline.flushno longer creates a sub-array if the batch is full, but instead usesbufferDatafor speed.WebGLPipeline.currentUnitis a new property that holds the most recently assigned texture unit. Treat as read-only.WebGLRenderer.setTextureSourceis a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.- The
WebGLRenderer.setTexture2Dmethod has been updated to use the new texture unit assignment. It no longer takes thetextureUnitorflushparameters and these have been removed from its method signature. WebGLRenderer.setTextureZerois a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.WebGLRenderer.clearTextureZerois a new method that clears the texture tha was bound to unit zero.WebGLRenderer.textureZerois a new property that holds the currently bound unit zero texture.WebGLRenderer.normalTextureis a new property that holds the currently bound normal map (texture unit one).WebGLRenderer.setNormalMapis a new method that sets the current normal map texture.WebGLRenderer.clearNormalMapis a new method that clears the current normal map texture.WebGLRenderer.resetTexturesis a new method that flushes the pipeline, resets all textures back to the temporary ones and resets the active texture counter.WebGLPipeline.bootwill now check all of the attributes and store the pointer location within the attribute entry.WebGLPipeline.bindno 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.isNewNormalMapis a new method that returns a boolean if the given parameters are not currently used.WebGLPipeline.forceZerois a new property that informs Game Objects if the pipeline requires a zero bound texture unit.WebGLPipeline.setAttribPointersis a new method that will set the vertex attribute pointers for the pipeline.WebGLRenderer.unbindTexturesis 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
Lightis dirty. - The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
- The
ForwardDiffuseLightPipeline.defaultNormalMapproperty has changed, it's now an object with aglTextureproperty that maps to the pipelines default normal map. - The
ForwardDiffuseLightPipeline.bootmethod has been changed to now generate a default normal map. - The
ForwardDiffuseLightPipeline.onBindmethod has been removed as it's no longer required. - The
ForwardDiffuseLightPipeline.setNormalMapmethod has been removed as it's no longer required. ForwardDiffuseLightPipeline.bindis a new method that handles setting-up the shader uniforms.- The
ForwardDiffuseLightPipeline.batchTexturemethod has been rewritten to use the Texture Tint Pipeline function instead. - The
ForwardDiffuseLightPipeline.batchSpritemethod has been rewritten to use the Texture Tint Pipeline function instead. ForwardDiffuseLightPipeline.lightCountis a new property that stores the previous number of lights rendered.ForwardDiffuseLightPipeline.getNormalMapis a new method that will look-up and return a normal map for the given object.
Lights
Light.dirtyis a new property that controls if the light is dirty, or not, and needs its uniforms updating.Lighthas been recoded so that all of its properties are now setters that activate itsdirtyflag.LightsManager.destroywill now clear thelightPoolarray when destroyed, where-as previously it didn't.LightsManager.cullnow 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.MVPis a new namespace under which the Model View Projection functions now live.projIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectIdentityprojPerspis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectPerspectivemodelRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateXmodelRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateYmodelRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.RotateZviewLoadis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoadviewRotateXis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateXviewRotateYis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateYviewRotateZis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewRotateZviewScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewScaleviewTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewTranslatemodelIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.IdentitymodelScaleis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ScalemodelTranslateis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.TranslateviewIdentityis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewIdentityviewLoad2Dis now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ViewLoad2DprojOrthois now available as a stand-alone functionPhaser.Renderer.WebGL.MVP.ProjectOrthoPhaser.Renderer.WebGL.MVP.SetIdentityis a new function the others use, to save on space.
New Features
WebGLRenderer.setInt1ivwill allow you to look-up and set a 1iv uniform on the given shader.
Updates and API Changes
Config.batchSizehas been increased from 2000 to 4096.- Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
StaticTilemapLayer.uploadwill now set the vertex attributes and buffer the data, and handles internal checks more efficiently.StaticTilemapLayernow includes theModelViewProjectionmixin, so it doesn't need to modify the pipeline during rendering.WebGLRenderer.textureFlushis a new property that keeps track of the total texture flushes per frame.- The
TextureTintStripPipelinenow extendsTextureTintPipelineand just changes the topolgy, vastly reducing the filesize.
Bug Fixes
RenderTexture.resize(which is called fromsetSize) wouldn't correctly set theTextureSource.glTextureproperty, leading tobindTexture: attempt to use a deleted objecterrors under WebGL.- The
MatterAttractorsplugin, 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.RotateTofunction 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
childrenwhen 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,SpriteWithDynamicBodyandSpriteWithStaticBody. Fix #4994 (thanks @samme @gnesher) Body.updateFromGameObjectis a new method that extracts the relevant code frompreUpdate, allowing you to read the body's new position and center immediately, before the next physics step. It also letsrefreshBodywork 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
updatestep, causing the position to be off. Fix #5204 (thanks @zackexplosion @samme) Arcade.Components.Size.setBodySizeis a new method available on Arcade Physics Game Objects that allows you to set the body size. This replacessetSizewhich is now deprecated. Fix #4786 (thanks @wingyplus)
New Features
- The Animation component has a new property
nextAnimsQueuewhich 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.setActiveis a new method that will set the active state of a Group, just like it does on other Game Objects (thanks @samme)Group.setNameis a new method that will set the name property of a Group, just like it does on other Game Objects (thanks @samme)TWEEN_STOPis a new event dispatched by a Tween when it stops playback (thanks @samme @RollinSafary)- You can now specify an
onStopcallback 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.wordWrapWidthlets you set the maximum width of a line of text (thanks @mikewesthad)TextStyle.wordWrapCallbackis a custom function that will is responsible for wrapping the text (thanks @mikewesthad)TextStyle.wordWrapCallbackScopeis the scope that will be applied when thewordWrapCallbackis invoked (thanks @mikewesthad)TextStyle.wordWrapUseAdvancedcontrols whether or not to use the advanced wrapping algorithm (thanks @mikewesthad)KeyboardPlugin.removeAllKeysis 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.RotateTois a new function that will position a point at the given angle and distance (thanks @samme)Display.Bounds.GetBoundsis a new function that will return the un-transformed bounds of the given Game Object as a Rectangle (thanks @samme)
Updates
- The
Pointer.dragStartX/YGlobalandPointer.dragX/Yvalues are now populated from theworldX/Y, which means using those values directly in Input Drag callbacks will now work when the Camera is zoomed. Fix #4755 (thanks @braindx) - The
browserfield has been added to the Phaserpackage.jsonpointing to thedist/phaser.jsumd 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.getBoundswill 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.statewill now be set to theFILE_LOADINGstate while loading andFILE_LOADEDafter loading (thanks @samme)BaseCamera.cullnow moves some of its calculations outside of the cull loop to speed it up (thanks @samme)SceneManager.createSceneFromInstancehad a small refactor to avoid a pointless condition (thanks @samme)
Bug Fixes
- Fixed a TypeError warning when importing JSON objects directly to the
urlargument of any of the Loader filetypes. Fix #5189 (thanks @awweather @samme) - The
NOOPfunction 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.checkDowndidn't set thedurationto zero if the parameter was omitted, causing it to always return false. Fix #5146 (thanks @lozzajp)- If you passed in an array of
childrenwhen 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 soundstop()will error (thanks @samme) - Using a Render Texture when you're also using the headless renderer would cause an error (thanks @samme)
Ellipse.setWidthwould incorrectly set thexRadiusto the diameter (thanks @rexrainbow)Ellipse.setHeightwould incorrectly set theyRadiusto the diameter (thanks @rexrainbow)- When specifically setting the
parentproperty in the Game Config tonullthe 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.startFullScreenwould fail in Safari on Mac OS, throwing afullscreenfailederror. It now triggers fullscreen mode correctly, as on other browsers. Fix #5143 (thanks @samme @novaknole) - Calling
setCropon 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
getTextBoundson 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
childrenwhen 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,SpriteWithDynamicBodyandSpriteWithStaticBody. Fix #4994 (thanks @samme @gnesher) Body.updateFromGameObjectis a new method that extracts the relevant code frompreUpdate, allowing you to read the body's new position and center immediately, before the next physics step. It also letsrefreshBodywork 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
updatestep, causing the position to be off. Fix #5204 (thanks @zackexplosion @samme) Arcade.Components.Size.setBodySizeis a new method available on Arcade Physics Game Objects that allows you to set the body size. This replacessetSizewhich is now deprecated. Fix #4786 (thanks @wingyplus)
New Features
- The Animation component has a new property
nextAnimsQueuewhich 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.setActiveis a new method that will set the active state of a Group, just like it does on other Game Objects (thanks @samme)Group.setNameis a new method that will set the name property of a Group, just like it does on other Game Objects (thanks @samme)TWEEN_STOPis a new event dispatched by a Tween when it stops playback (thanks @samme @RollinSafary)- You can now specify an
onStopcallback 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.wordWrapWidthlets you set the maximum width of a line of text (thanks @mikewesthad)TextStyle.wordWrapCallbackis a custom function that will is responsible for wrapping the text (thanks @mikewesthad)TextStyle.wordWrapCallbackScopeis the scope that will be applied when thewordWrapCallbackis invoked (thanks @mikewesthad)TextStyle.wordWrapUseAdvancedcontrols whether or not to use the advanced wrapping algorithm (thanks @mikewesthad)KeyboardPlugin.removeAllKeysis 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.RotateTois a new function that will position a point at the given angle and distance (thanks @samme)Display.Bounds.GetBoundsis a new function that will return the un-transformed bounds of the given Game Object as a Rectangle (thanks @samme)
Updates
- The
Pointer.dragStartX/YGlobalandPointer.dragX/Yvalues are now populated from theworldX/Y, which means using those values directly in Input Drag callbacks will now work when the Camera is zoomed. Fix #4755 (thanks @braindx) - The
browserfield has been added to the Phaserpackage.jsonpointing to thedist/phaser.jsumd 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.getBoundswill 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.statewill now be set to theFILE_LOADINGstate while loading andFILE_LOADEDafter loading (thanks @samme)BaseCamera.cullnow moves some of its calculations outside of the cull loop to speed it up (thanks @samme)SceneManager.createSceneFromInstancehad a small refactor to avoid a pointless condition (thanks @samme)
Bug Fixes
- Fixed a TypeError warning when importing JSON objects directly to the
urlargument of any of the Loader filetypes. Fix #5189 (thanks @awweather @samme) - The
NOOPfunction 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.checkDowndidn't set thedurationto zero if the parameter was omitted, causing it to always return false. Fix #5146 (thanks @lozzajp)- If you passed in an array of
childrenwhen 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 soundstop()will error (thanks @samme) - Using a Render Texture when you're also using the headless renderer would cause an error (thanks @samme)
Ellipse.setWidthwould incorrectly set thexRadiusto the diameter (thanks @rexrainbow)Ellipse.setHeightwould incorrectly set theyRadiusto the diameter (thanks @rexrainbow)- When specifically setting the
parentproperty in the Game Config tonullthe 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.startFullScreenwould fail in Safari on Mac OS, throwing afullscreenfailederror. It now triggers fullscreen mode correctly, as on other browsers. Fix #5143 (thanks @samme @novaknole) - Calling
setCropon 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
getTextBoundson 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.impactproperty 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.GetEasedPointsis 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.withCredentialsis a new boolean property that controls thewithCredentialssetting 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.loaderWithCredentialsis the new global setting forXHRSettings.withCredentials.Camera.renderToGameis a new property used in conjunction withrenderToTexture. 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.setRenderToTexturehas a new optional parameterrenderToGamewhich sets theCamera.renderToGameproperty, 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
pivotproperty when using JSON Array or Hash, however the Texture Packer Phaser export uses theanchorproperty. 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.FromXYis a new function that will create the smallest Rectangle containing two coordinate pairs, handy for marquee style selections (thanks @samme)PathFollower.pathDeltais 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.fuzzyEqualsis a new method that will check whether the Vector is approximately equal to a given Vector (thanks @samme)Vector2.setAngleis a new method that will set the angle of the Vector (thanks @samme)Vector2.setLengthis a new method that will set the length, or magnitude of the Vector (thanks @samme)Vector2.normalizeLeftHandis a new method that will rotate the Vector to its perpendicular, in the negative direction (thanks @samme)Vector2.limitis a new method that will limit the length, or magnitude of the Vector (thanks @samme)Vector2.reflectis a new method that will reflect the Vector off a line defined by a normal (thanks @samme)Vector2.mirroris a new method that will reflect the Vector across another (thanks @samme)Vector2.rotateis a new method that will rotate the Vector by an angle amount (thanks @samme)Math.Angle.Randomis a new function that will return a random angle in radians between -pi and pi (thanks @samme)Math.Angle.RandomDegreesis a new function that will return a random angle in degrees between -180 and 180 (thanks @samme)Physics.Arcade.World.fixedStepis 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.getTangentis a new method that gets a unit vector tangent at a relative position on the path (thanks @samme)DataManager.incis 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.toggleis 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 objectsand export them withpoint: true. Equally, Sprites generated viacreateFromObjectsare 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 andcreateFromObjectsplease re-test your maps against this release of Phaser (thanks @samme) - You can now use Blob URLs when loading
Audioobjects via the Loader (thanks @aucguy) - You can now use Blob URLs when loading
Videoobjects 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
headersto define an object containing multiple headers, all of which will be sent with the xhr request (thanks @jorbascrumps) Camera.rotateTois 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
XHRLoaderwill now use theXHRSettings.withCredentialsas set in the file or global loader config.Animation.setCurrentFramewill no longer try to callsetOriginorupdateDisplayOriginif the Game Object doesn't have the Origin component, preventing unknown function errors.MatterTileBodynow extendsEventEmitter, meaning you can listen to collision events from Tiles directly and it will no longer throw errors aboutgameObject.emitnot working. Fix #4967 (thanks @reinildo)- Added
MatterJS.BodyTypetoGameObject.bodytype. Fix #4962 (thanks @meisterpeeps) - The
JSONHashloader didn't load custom pivot information, butJSONArraydid. So that functionality has been duplicated into theJSONHashfile 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)
collideSpriteVsGroupnow exits early when the Sprite hascheckCollision.none, skipping an unnecessary iteration of the group (thanks @samme)collideSpriteVsGroupwhen looping through the tree results now skips bodies withcheckCollision.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
PathFollowerwas at the end of the path or not was incorrect (thanks @samme) - Creating an
Arcade Physics Bodyfrom 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 Bodyfrom 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 Bodycenter was incorrect after construction. Probably caused problems with circle collisions. Fix #4770 (thanks @samme) - An Arcade Physics Body
centerandpositionare now correct after construction and before preUpdate(), for any Game Object origin or scale (thanks @samme) - When calling
Body.setSizewith thecenterparameter astruethe calculated offset would be incorrect for scaled Game Objects. The offset now takes scaling into consideration (thanks @samme) HTML5AudioFile.loadwould throw an error in strict mode (thanks @samme)- When using the
No AudioSound Manager, callingdestroy()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
TextureTintPipelineis 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
datawasn't sent to the Scenewakemethod. 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_COMPLETEevent 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 scenesupdatefunction is called beforecreate, likely causing an error. Fix #5065 (thanks @samme) Circle.GetPointswill now check thatstepRateis > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)Ellipse.GetPointswill now check thatstepRateis > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)Line.GetPointswill now check thatstepRateis > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)Polygon.GetPointswill now check thatstepRateis > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)Rectangle.GetPointswill now check thatstepRateis > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)Triangle.GetPointswill now check thatstepRateis > 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.isStringfunction would cause a 'TypeError: Invalid calling object' in Internet Explorer (thanks @samme) Arcade.Body.checkCollision.nonedid not prevent collisions with Tiles. Now it does (thanks @samme)- When running in HEADLESS mode, using a
TextGame Object would cause a runtime error "Cannot read property gl of null". Fix #4976 (thanks @raimon-segura @samme) - The Tilemap
LayerDataclasspropertiesproperty 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) AudioFileandVideoFilehad their state set toundefinedinstead ofFILE_PROCESSING(thanks @samme)Container.getBoundswould 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
yoyoandrepeatDelayset will respect the delay after each yoyo runs (thanks @cruzdanilo) CanvasTexture.setSizeforgot to update thewidthandheightproperties 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
typesfolder :) MatterDebugConfigis 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 whenshowJointis 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 whenshowConvexHullsis set.World.renderBodyis 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.renderConstraintis 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.renderConvexHullis 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.renderGridis a new method that will render the broadphase Grid to the given graphics instance.World.renderBodyBoundsis a new method that will render the bounds of all the given bodies to the given graphics instance.World.renderBodyAxesis a new method that will render the axes of all the given bodies to the given graphics instance.World.renderBodyVelocityis a new method that will render a velocity line for all the given bodies to the given graphics instance.World.renderSeparationsis a new method that will render the separations in the current pairs list to the given graphics instance.World.renderCollisionsis a new method that will render the collision points and normals in the current pairs list to the given graphics instance.World.getAllBodiesis a new method that will return all bodies in the Matter World.World.getAllConstraintsis a new method that will return all constraints in the Matter World.World.getAllCompositesis a new method that will return all composites in the Matter World.MatterPhysics.compositeis a new reference to theMatter.Compositemodule for easy access from within a Scene.MatterPhysics.detectoris a new reference to theMatter.Dectectormodule for easy access from within a Scene.MatterPhysics.gridis a new reference to theMatter.Gridmodule for easy access from within a Scene.MatterPhysics.pairis a new reference to theMatter.Pairmodule for easy access from within a Scene.MatterPhysics.pairsis a new reference to theMatter.Pairsmodule for easy access from within a Scene.MatterPhysics.queryis a new reference to theMatter.Querymodule for easy access from within a Scene.MatterPhysics.resolveris a new reference to theMatter.Resolvermodule for easy access from within a Scene.MatterPhysics.satis a new reference to theMatter.SATmodule for easy access from within a Scene.MatterPhysics.constraintis a new reference to theMatter.Constraintmodule for easy access from within a Scene.MatterPhysics.compositesis a new reference to theMatter.Compositesmodule for easy access from within a Scene.MatterPhysics.axesis a new reference to theMatter.Axesmodule for easy access from within a Scene.MatterPhysics.boundsis a new reference to theMatter.Boundsmodule for easy access from within a Scene.MatterPhysics.svgis a new reference to theMatter.Svgmodule for easy access from within a Scene.MatterPhysics.vectoris a new reference to theMatter.Vectormodule for easy access from within a Scene.MatterPhysics.verticesis a new reference to theMatter.Verticesmodule for easy access from within a Scene.BEFORE_ADDis a new Event dispatched byMatter.Worldwhen a Body or Constraint is about to be added to the World.AFTER_ADDis a new Event dispatched byMatter.Worldwhen a Body or Constraint has been added to the World.BEFORE_REMOVEis a new Event dispatched byMatter.Worldwhen a Body or Constraint is about to be removed from the World.AFTER_REMOVEis a new Event dispatched byMatter.Worldwhen a Body or Constraint has been removed from the World.Body.render.lineOpacityis a new property on the Matter Body object that allows for custom debug rendering.Body.render.lineThicknessis a new property on the Matter Body object that allows for custom debug rendering.Body.render.fillOpacityis a new property on the Matter Body object that allows for custom debug rendering.World.setCompositeRenderStyleis a new method that lets you quickly set the render style values on the children of the given compposite.World.setBodyRenderStyleis a new method that lets you quickly set the render style values on the given Body.World.setConstraintRenderStyleis a new method that lets you quickly set the render style values on the given Constraint.- You can now set
restingThreshin the Matter Configuration file to adjust the Resolver property. - You can now set
restingThreshTangentin the Matter Configuration file to adjust the Resolver property. - You can now set
positionDampenin the Matter Configuration file to adjust the Resolver property. - You can now set
positionWarmingin the Matter Configuration file to adjust the Resolver property. - You can now set
frictionNormalMultiplierin the Matter Configuration file to adjust the Resolver property. MatterPhysics.containsPointis a new method that returns a boolean if any of the given bodies intersect with the given point.MatterPhysics.intersectPointis a new method that checks which bodies intersect with the given point and returns them.MatterPhysics.intersectRectis 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.intersectRayis 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.intersectBodyis 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.overlapis a new method that takes a target body and checks to see if it overlaps with any of the bodies given. If they do, optionalprocessandoverlapcallbacks are invoked, passing the overlapping bodies to them, along with additional collision data.MatterPhysics.setCollisionCategoryis 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.setCollisionGroupis 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.setCollidesWithis 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.centerOfMassis 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.centerOffsetis 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.pointAWorldis a new method added to Matter that returns the world-space position ofconstraint.pointA, accounting forconstraint.bodyA.Constraint.pointBWorldis a new method added to Matter that returns the world-space position ofconstraint.pointB, accounting forconstraint.bodyB.Body.setCentreis 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.scaleis a new read-only vector that holds the most recent scale values as passed toBody.scale.Matter.Bodies.flagCoincidentPartsis a new function that will flags all internal edges (coincident parts) on an array of body parts. This was previously part of thefromVerticesfunction, but has been made external for outside use.Matter.getMatterBodiesis 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.hasis a new method that will take a Matter Body, or Game Object, and search the world for it. If found, it will returntrue.- 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
runnerproperty 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, setrunner: { isFixed: true }. Body.onCollideCallbackis a new Matter Body property that can point to a callback to invoke when the body starts colliding.Body.onCollideEndCallbackis a new Matter Body property that can point to a callback to invoke when the body stops colliding.Body.onCollideActiveCallbackis a new Matter Body property that can point to a callback to invoke for the duration the body is colliding.Body.onCollideWithis a new Matter Body property that holds a mapping between bodies and collision callbacks.MatterGameObject.setOnCollideis a new method available on any Matter Game Object, that sets a callback that is invoked when the body collides with another.MatterGameObject.setOnCollideEndis a new method available on any Matter Game Object, that sets a callback that is invoked when the body stops colliding.MatterGameObject.setOnCollideActiveis 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.setOnCollideWithis 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.gravityScaleis a new vector property that allows you to scale the effect of world gravity on a specific Body.MatterPhysics._tempVec2is a new private internal vector used for velocity and force calculations.MatterPhysics.setVelocityis 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.setVelocityXis 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.setVelocityYis 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.setAngularVelocityis 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.applyForceis 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.applyForceFromPositionis 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.fromSVGis a new method that allows you to create a Body from the given SVG path data.- The
Matter.Factory.velocitymethod has been removed. Please now useMatterPhysics.setVelocityinstead. - The
Matter.Factory.angularVelocitymethod has been removed. Please now useMatterPhysics.setAngularVelocityinstead. - The
Matter.Factory.forcemethod has been removed. Please now useMatterPhysics.applyForceinstead. MatterBodyConfigis 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.MatterBodyRenderConfigis 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.MatterChamferConfigis 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.MatterCollisionFilteris 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.MatterConstraintConfigis 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.MatterConstraintRenderConfigis 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.MatterSetBodyConfigis 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.getConstraintLengthis 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.alignBodyis 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 theBOTTOM_LEFT, orTOP_CENTER, or a coordinate. Alignment is based on the body bounds.Phaser.Types.Physics.Matter.MatterBodyis 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.BodyBoundsis 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 viathis.matter.bodyBounds.- The method signature for
Matter.PhysicsEditorParser.parseBodyhas changed. It now takes(x, y, config, options)and no longer haswidthandheightparameters. Please see the updated documentation for more details if you were calling this method directly. MatterPhysics.fromPhysicsEditoris 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.PhysicsJSONParseris 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.fromJSONis a new method that will create a body from a JSON physics data file.- The
SetBodyMatter component can now automatically use shapes created in the Phaser Physics Tracer App in the JSON data format. Matter.Components.Sleep.setToSleepis 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.setAwakeis 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
debugproperty in the Matter World Config is now aMatterDebugConfigoption instead of a boolean. However, if a boolean is given, it will use the default debug config values. - The following
MatterWorldConfigoptions have now been removed:debugShowBody,debugShowStaticBody,debugBodyColor,debugBodyFillColor,debugStaticBodyColor,debugShowJoint,debugJointColor,debugWireframes,debugShowInternalEdges,debugShowConvexHulls,debugConvexHullColoranddebugShowSleeping. These can all be set via the newMatterDebugConfigobject instead. - The object
World.defaultshas been removed. Defaults are now access viaWorld.debugDefaults. World.renderBodieshas been rewritten to cache commonly-used values and avoid a situation when a single body would be rendered twice.- The private method
World.renderConvexHullshas been removed as it's no longer used internally. - The private method
World.renderWireframeshas been removed as it's no longer used internally. - The method
World.fromPathhas been removed. This was never used internally and you can get the same results by callingVertices.fromPath. - The
World.setBoundsargumentthicknessnow defaults to 64, not 128, to keep it matching the Matter World Config. - The
Body.render.fillStyleproperty that existed on the Matter Body object has been removed and replaced withfillColor. - The
Body.render.strokeStyleproperty that existed on the Matter Body object has been removed and replaced withlineColor. Matter.Body.render.sprite.xOffsetandyOffsetare 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 tosetExistingBody.- The
Matter.Mass.centerOfMasscomponent property now returns the pre-calculated BodycenterOfMassproperty, 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 newcenterOffsetvalues 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.PhysicsEditorParserhas been updated so it no longer needs to set the render offsets, and instead uses the center of mass values. - If the
Matter.Bodyconfig doesn't contain apositionproperty, it will now default to usingVertices.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.parseVerticesnow usesBodies.flagCoincidentPartsto avoid duplicating code.MatterGameObjecthas a new optional boolean constructor parameteraddToWorldwhich 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.setExistingBodyfunction, which all Matter Game Objects have, has a new parameteraddToWorldwhich 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. PointerConstrainthas 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: falsein your Matter Config and it will reset gravity from the defaults to zero. - The internal Matter
Composite.setModifiedfunction will now emit acompositeModifiedevent, which the Matter World listens for, if debug draw is enabled, so it can update the composite children render styles. Matter.PhysicsEditorParser.parseBodycan 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.PhysicsEditorParserhad 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.smoothStepis 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 correspondingFPSConfigproperty.Phaser.Math.Distance.BetweenPointsis a new function that will return the distance between two Vector2-like objects (thanks @samme)Phaser.Math.Distance.BetweenPointsSquaredis a new function that will return the squared distance between two Vector2-like objects (thanks @samme)Phaser.Math.Distance.Chebyshevis a new function that will return the Chebyshev (or chessboard) distance between two Vector2-like objects (thanks @samme)Phaser.Math.Distance.Snakeis a new function that will return the rectilinear distance between two Vector2-like objects (thanks @samme)ParticleEmitter.setTintis a new method that will set the tint of emitted particles for the given Emitter only (thanks @samme)ParticleEmitter.removeis a new method that will remove the Emitter from its Emitter Manager (thanks @samme)ParticleEmitterManager.removeEmitteris a new method that will remove the given emitter from the manager, if the emitter belongs to it (thanks @samme)AlphaSingleis 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 newDisplay.Align.To.QuickSetfunction) 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.getDatais a new method that will return any data that was sent to the Scene by another Scene, i.e. during arunorlaunchcommand. You can access it viathis.sys.getData()from within your Scene.Group.internalCreateCallbackis a new optional callback that is invoked whenever a child is added to a Group. This is the same ascreateCallbackexcept 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.internalRemoveCallbackis a new optional callback that is invoked whenever a child is removed from a Group. This is the same asremoveCallbackexcept 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.deltaXFinalis 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 thepostUpdatephase, so must be listened for accordingly (thanks Bambosh)Body.deltaYFinalis 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 thepostUpdatephase, so must be listened for accordingly (thanks Bambosh)Body._txis a new internal private var, holding the Arcade Physics Body combined total delta x value.Body._tyis a new internal private var, holding the Arcade Physics Body combined total delta y value.LineCurve.getUtoTmappinghas been updated to returnudirectly to avoid calculations as it's identical totin a Line (thanks @rexrainbow)Curve.getSpacedPointswill 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
ShapeGame 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
ContainerGame 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
DOMElementGame 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
GraphicsGame 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. TweenDatahas a new property calledpreviouswhich holds the eased property value prior to the update.- The
TWEEN_UPDATEevent now sends two new parameters to the handler:currentandpreviouswhich contain the current and previous property values. - During
collideSpriteVsGroupchecks it will now skip bodies that are disabled to save doing acontainstest (thanks @samme) Display.Align.In.QuickSetnow acceptsLEFT_BOTTOMasBOTTOM_LEFT,LEFT_TOPasTOP_LEFT,RIGHT_BOTTOMasBOTTOM_RIGHTandRIGHT_TOPasTOP_RIGHT. Fix #4927 (thanks @zaniar)PhysicsGroupnow uses the newinternalCreateCallbackandinternalRemoveCallbackto handle its body creation and destruction, allowing you to use your owncreateCallbackandremoveCallbackas defined in the Group config. Fix #4420 #4657 #4822 (thanks @S4n60w3n @kendistiller @scrubperson)DOMElementhas a new private methodhandleSceneEventwhich 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 thepreDestroymethod.- A
DOMElementwill 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
maxWidthset 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.destroyis running, Scenes are now destroyed before plugins, avoiding bugs when closing down plugins and deleting Render Textures. Fix #4849 #4876 (thanks @rexrainbow @siyuanqiao) - The
MeshandQuadGame Objects have had theGetBoundscomponent removed as it cannot operate on a Mesh as they don't have origins. Fix #4902 (thanks @samme) - Setting
lineSpacingin the Text Game Object style config would set the value but not apply it to the Text, leaving you to callupdateTextyourself. 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 callstopFullScreenshould it be triggered outside of Phaser (thanks @AdamXA) - The
Tilemaps.Tile.tintproperty 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.destroymethod wasn't being called when the GameDESTROYevent was dispatched, causing minor gc to build up. The destroy method will now be called properly on game destruction. Fix #4944 (thanks @sunshineuoow) FacebookInstantGamesPlugin.showAdandshowVideowill 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
_pausedwouldn'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.GridAlignif you setwidthto -1 it would align the items vertically, instead of horizontally. It now aligns them horizontally ifwidthis set, or vertically ifheightis set. Fix #4899 (thanks @BenjaVR) - A
PathFollowerwith 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
DOMElementwould 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
MultiAtlasFileit expected the atlas URL to be in theurlproperty, however the docs and file config expected it inatlasURL. 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
mipmapFilterproperty, which is a string, such as 'NEARESTMIPMAPNEAREST'. Or, you can set the newWebGLRenderer.mipmapFilterproperty 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 Sceneinitmethod 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.setMaxWidthis 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 thanmaxWidthwill 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.wordWrapCharCodeis a new property that works withsetMaxWidththat allows you to control which character code causes a line-wrap. By default it is 32 (a space character).ArcadePhysics.closestnow has an optionaltargetsargument. 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.furthestnow has an optionaltargetsargument. 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.CreateGroupLayeris 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.getImageLayerNamesis a new method that returns a list of all valid imagelayer names loaded in the Tilemap (thanks @Olliebrown)Tilemap.getObjectLayerNamesis a new method that returns a list of all valid objectgroup names loaded in the Tilemap (thanks @Olliebrown)Tilemap.getTileLayerNamesis a new method that returns a list of all valid tilelayer names loaded in the Tilemap (thanks @Olliebrown)- When
forceSetTimeOutis set totruein the Game Config, you can now set the target frame rate by setting thefps.targetvalue (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_INTEGERis 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_INTEGERis a new math const that stores the maximum safe integer for browsers that don't provide this, such as IE (thanks @jronn)KeyCodes.NUMPAD_ADDhas been added to the keycodes list (thanks @Martin-Antonov)KeyCodes.NUMPAD_SUBTRACThas been added to the keycodes list (thanks @Martin-Antonov)Video.removeVideoElementOnDestroyis 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.SetScrollFactoris a new Action that will set the scroll factor on an array of Game Objects, including stepped incremental changes per item (thanks @rexrainbow)Actions.SetScrollFactorXis 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.SetScrollFactorYis 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
Groupconfig object now supports use of thesetScrollFactorproperty to set the value on each child of the Group (thanks @rexrainbow) Group.propertyValueSetis a new method that sets a given property on each Group member (thanks @rexrainbow)Group.propertyValueIncis a new method that adds an amount to a given property on each Group member (thanks @rexrainbow)Group.setXis a new method that sets the x coordinate on each Group member (thanks @rexrainbow)Group.setYis a new method that sets the y coordinate on each Group member (thanks @rexrainbow)Group.setXYis a new method that sets the x and y coordinate on each Group member (thanks @rexrainbow)Group.incXis a new method that increments the x coordinate on each Group member (thanks @rexrainbow)Group.incYis a new method that increments the y coordinate on each Group member (thanks @rexrainbow)Group.incXYis a new method that increments the x and y coordinate on each Group member (thanks @rexrainbow)Group.shiftPositionis a new method that iterates the Group members and shifts the position of each to the previous members position (thanks @rexrainbow)Group.angleis a new method that sets the angle property on each Group member (thanks @rexrainbow)Group.rotateis a new method that sets the rotation property on each Group member (thanks @rexrainbow)Group.rotateAroundis a new method that rotates each Group member around the given point, by the given angle (thanks @rexrainbow)Group.rotateAroundDistanceis a new method that rotates each Group member around the given point, by the given angle and distance (thanks @rexrainbow)Group.setAlphais a new method that sets the alpha property on each Group member (thanks @rexrainbow)Group.setTintis a new method that sets the tint property on each Group member (thanks @rexrainbow)Group.setOriginis a new method that sets the origin property on each Group member (thanks @rexrainbow)Group.scaleXis a new method that sets the x scale on each Group member (thanks @rexrainbow)Group.scaleYis a new method that sets the y scale on each Group member (thanks @rexrainbow)Group.scaleXYis a new method that sets the x and y scale on each Group member (thanks @rexrainbow)Group.setBlendModeis a new method that sets the blend mode on each Group member (thanks @rexrainbow)Group.setHitAreais a new method that passes all Group members to the Input Plugin to enable them for input (thanks @rexrainbow)Group.shuffleis a new method that shuffles all of the Group members in place (thanks @rexrainbow)Group.setVisibleis a new method that sets the visible state on each Group member (thanks @rexrainbow)WebAudioSoundManager.setAudioContextis 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.typeis a new property that holds a string-based name of the Game Object type, as with other GO's (thanks @samme)Arade.Group.typeis a new property that holds a string-based name of the Game Object type, as with other GO's (thanks @samme)Arcade.StaticGroup.typeis a new property that holds a string-based name of the Game Object type, as with other GO's (thanks @samme)ArcadePhysics.overlapCircis 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.getPointscan now take an optional array as the 3rd parameter in which to store the points results (thanks @rexrainbow)Line.arcLengthDivisionsnow overrides the default Curve value and is set to 1 to optimize the amount of points returned for a Line curve (thanks @rexrainbow)ArcadePhysics.closestwill now no longer ever return the source in the target results (thanks @samme)ArcadePhysics.furthestwill now no longer ever return the source in the target results (thanks @samme)RequestAnimationFrame.targetis a new property that controls the fps rate (in ms) when setTimeout is used (thanks @pavels)- The
WebAudioSoundManager.unlockmethod will now listen forkeydownevents in order to unlock the Audio Context, as well as touch and pointer events, making it more accessible (thanks Nick Tipping) - The
requestAnimationFramepolyfill no longer expects a Browserify environment and useswindowthrough-out, it also no longer adds in the same as performance.now does. BitmapText.getTextBoundsdidn't reset the dirty flag, causing theGetBitmapTextSizefunction 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.GetScreenOrientationwas returning the wrong consts from the Scale Manager (thanks @jcyuan)- When using
Input.enableDebugon 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.dragDistanceThresholdwas 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.convertLayerToStaticwould throw an error when used multiple times, due to an error with the layer index count. Fix #4737 (thanks @Olliebrown @Vegita2)- The
Tweenclass now uses a cached MAXSAFEINTEGER making it compatible with Internet Explorer (thanks @jronn) - The
StaggerBuilderclass now uses a cached MAXSAFEINTEGER making it compatible with Internet Explorer (thanks @jronn) - The
Rectangle.FromPointsfunction now uses a cached MINSAFEINTEGER making it compatible with Internet Explorer (thanks @jronn) - The
Videoclass now uses a cached MINSAFEINTEGER making it compatible with Internet Explorer (thanks @jronn) - The
Pathclass now uses a cached MINSAFEINTEGER making it compatible with Internet Explorer (thanks @jronn) Video.destroyhas been renamed toVideo.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
HTMLVideoElementbefore creating one (thanks @jcyuan) - The
DOM.GetScreenOrientationfunctions would return out-dated consts (thanks @jcyuan) - When calling
TileSprite.setTextureorsetFrame, if the new frame size didn't match the old one, the new fill pattern would become distorted and thepotWidthandpotHeightvalues would be incorrect. - Timeline callbacks with extra parameters like
onStartwould 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-pluginplugin has been moved to a devDependency (thanks @noseglid)
Bug Fixes
UpdateList.shutdownwasn't removing the Scene Update event listener, causing actions to be multiplied on Scene restart (such as animation playback). Fix #4799 (thanks @jronn)Container.maskwouldn'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.setCollisionwould cause anindexOferror when trying to access the layer data. Fix #4800 (thanks @PavelMishin)SceneManager.run(and consequentlyScenePlugin.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 theSystems.isPausedfunction 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.VideoFileis a new Video File Loader File Type, used for preloading videos as streams or blobs.WebGLRenderer.createVideoTextureis a new method that will create a WebGL Texture from the given Video Element.WebGLRenderer.updateVideoTextureis a new method that will update a WebGL Texture from the given Video Element.TextureSource.isVideois a new boolean property that is set when the Texture Source is backed by an HTML Video Element.Cache.videois a new global cache that store loaded Video content.Device.Video.h264Videohas been renamed toDevice.Video.h264to keep it in-line with the Audio Device names.Device.Video.hlsVideohas been renamed toDevice.Video.hlsto keep it in-line with the Audio Device names.Device.Video.mp4Videohas been renamed toDevice.Video.mp4to keep it in-line with the Audio Device names.Device.Video.oggVideohas been renamed toDevice.Video.oggto keep it in-line with the Audio Device names.Device.Video.vp9Videohas been renamed toDevice.Video.vp9to keep it in-line with the Audio Device names.Device.Video.webmVideohas been renamed toDevice.Video.webmto 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.setPathto 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
showAdorshowVideoAdwill 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
gameStartedin 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 methodgameStartedHandlerand will redirect the flow accordingly based on asset loading. Fix #4550 (thanks @bchee) - The documentation for the
chooseContextmethod has been fixed. Fix #4425 (thanks @krzysztof-grzybek) Leaderboard.getConnectedScoresincorrectly specified two parameters, neither of which were used. Fix #4702 (thanks @NokFrt)Leaderboardextends 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.prevFrameis 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._resetflag was removed and replaced it with a check ofBody.moves. The flag only turned on whenmoveswas true, and never turned off.- Added a reset of
previn Arcade.Body#step. This fixes the friction issue. - Stopped the
Body.postUpdatemethod from setting_dx,_dy, andprev. 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
blockedchecks fromTileCheckXandTileCheckY. 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.antialiasGLis a new boolean that allows you to set theantialiasproperty of the WebGL context during creation, without impacting any subsequent textures or the canvas CSS.InteractiveObject.alwaysEnabledis a new boolean that allows an interactive Game Object to always receive input events, even if it's invisible or won't render.Bob.setTintis 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
UpdateListnow emits two new events: 'add' and 'remove' when children are added and removed from it. Fix #3487 (thanks @hexus) - The
Tilemap.setCollisionmethod has a new optional boolean parameterupdateLayer. If set totrue, it will update all of the collision settings of all tiles on the layer. Iffalseit 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 theSetCollision,SetCollisionBetweenandDynamicTilemapLayer.setCollisionmethods (thanks @tarsupin) ArcadePhysics.Body.setBoundsRectangleis 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.customBoundsRectangleis a new property used for custom bounds collision (thanks @francois-n-dream)- The Arcade Physics Group has a new config object property
customBoundsRectanglewhich, if set, will set the custom world bounds for all Bodies that Group creates (thanks @francois-n-dream) WebGLRenderer.createTexture2Dhas a new optional parameterflipYwhich sets theUNPACK_FLIP_Y_WEBGLflag of the uploaded texture.WebGLRenderer.canvasToTexturehas a new optional parameterflipYwhich sets theUNPACK_FLIP_Y_WEBGLflag of the uploaded texture.WebGLRenderer.createCanvasTextureis a new method that will create a WebGL Texture based on the given Canvas Element.WebGLRenderer.updateCanvasTextureis a new method that will update an existing WebGL Texture based on the given Canvas Element.WebGLRenderer.createVideoTextureis a new method that will create a WebGL Texture based on the given Video Element.WebGLRenderer.updateVideoTextureis a new method that will update an existing WebGL Texture based on the given Video Element.TextureSource.flipYis a new boolean that controls if theUNPACK_FLIP_Y_WEBGLflag is set when a WebGL Texture is uploaded.TextureSource.setFlipYis a new method that toggles theTextureSource.flipYproperty.
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._savedKeyproperty has been removed as it wasn't used anywhere internally. - A
hasOwnPropertycheck has been applied to theSceneManager.createSceneFromObjectmethod when parsing additional properties in theextendobject (thanks @halilcakar) - The
Blitter.dirtyflag is no longer set if the render state of a Bob is changed to make it invisible (thanks @rexrainbow) WebGLPipeline.addAttributewill now automatically update the vertextComponentCount for you, without you having to do it manually any more (thanks @yhwh)MultiFilehas three new internal properties:baseURL,pathandprefixwhich allow them to retain the state of the loader at the time of creation, to be passed on to all child-files. Fix #4679.LoaderPluginandMultiFilehave a new private propertymultiKeyIndexwhich 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.isGLTexturenow checks if the browser supportsWebGLTexturebefore 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.ToJSONwill no longer output thescaleModein the json because it's not a valid Game Object property.TextureSource.setFilterwill now set thescaleModeto the given filter.CanvasInterpolationhas updated the order of the CSS properties so thatcrisp-edgescomes after the browser prefix versions.- The
CanvasRenderer.scaleModeproperty has been removed as it was never set or used internally. - The
CanvasRenderer.currentScaleModeproperty has been removed as it was never set or used internally. - The
BuildGameObjectfunction will no longer setscaleModebecause it's not a valid Game Object property. CanvasRenderer.antialiasis a new property, populated by the game config property of the same name (or via thepixelArtproperty) that will tell the canvas renderer what to set image interpolation to during rendering of Sprites.SetTransformwill 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
ProcessQueuestruct now extends Event Emitter and will emitPROCESS_QUEUE_ADD_EVENTwhen a new item is added to it. - The
ProcessQueuestruct now extends Event Emitter and will emitPROCESS_QUEUE_REMOVE_EVENTwhen an item is removed from it. ProcessQueue.removeAllis a new method that will remove all active entries from the queue.ProcessQueue.lengthis a new property that returns the size of the active list.UpdateListnow extends theProcessQueuestruct and uses all of its methods for list management, instead of doing it directly. This means private properties such asUpdateList._listno 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.forEachActiveSoundwill now only invoke the callback if the sound actually exists and isn't pending removal. Fix #3383 (thanks @DouglasLapsley)MouseManager.targetcan now be defined as either a string or by passing an HTMLElement directly. Fix #4353 (thanks @BigZaphod)- The
BasePlugin.bootmethod has been removed and moved toScenePlugin.bootas it's a Scene-level method only (thanks @samme) - The
BasePlugin.sceneandBasePlugin.systemsproperties have been removed and are defined inScenePlugin, as they are Scene-level properties only (thanks @samme) - The
Tween.getValuemethod 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.createTexture2Dhas a new optional parameterforceSize, 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.setTexturemethod 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.getcan now accept either a string-based key, or a Texture instance, as its parameter.SceneManager.stopand the matchingScenePlugin.stopnow have an optionaldataparameter, which is passed to the Scene shutdown method. Fix #4510 (thanks @Olliebrown @GetsukenStudios)Cameras.BaseCamerais now exposed in the namespace, allowing you to access them directly (thanks @rexrainbow)- Shaders have a new optional constructor parameter
textureDatawhich allows you to specify additional texture data, especially for NPOT textures (thanks @cristlee) TouchManager.disableContextMenuis a new method that will try to disable the context menu on touch devices, if the Game ConfigdisableContextMenuis 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.shutdownwould try to dispose of thesceneRenderer, but the property isn't set for Canvas.ArcadePhysics.Body.checkWorldBoundswould incorrectly report as being on the World bounds if theblocked.noneflag had been toggled elsewhere in the Body. It now only sets if it toggles a new internal flag (thanks Pablo)RenderTexture.resizewouldn't update the CanvasTexture width and height, causing the cal to draw or drawFrame to potentially distort the texture (thanks @yhwh)InputPlugin.processDragMovehas been updated so that the resultingdragXanddragYvalues, 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
displayOriginvalues are now automatically updated if you callsetSizeon the Render Texture. Fix #4757 (thanks @rexrainbow) onTouchStart,onTouchEndandonTouchMovewill now check forevent.cancelablebefore 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.shutdowncould 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.hitTestwould 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.separateCirclehas had the velocity scaling moved to after the angle is calculated, fixing a weird collision issue whenBody.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.updateTowould 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)
MultiAtlasFilesthat 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
MultiAtlasFileused the same internal file name for its images, subsequent multi-atlases would fail to load. Fix #4330 (thanks @giviz) MultiAtlasFileswould 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.fillwasn'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.setOriginwouldn't change the origin when using the Canvas Renderer, only in WebGL. It now sets the origin regardless of renderer. Fix #4108 (thanks @garethwhittaker)DynamicBitmapTextwouldn't respect the multi-line alignment values when using the Canvas Renderer. It now uses them in the line calculations.DynamicBitmapTextandBitmapTextwouldn'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
uInverseRotationMatrixto compute the lighting correctly (thanks @gogoprog) - Matter.js Body wasn't setting the part angles correctly in
Body.update(thanks @Frozzy6) ScaleManager.startFullscreennow 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 :)
StaggerBuilderis 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.Tweennow extends the Event Emitter class, allowing it to emit its own events and be listened to.Tween.ACTIVE_EVENTis a new event that is dispatched when a tween becomes active. Listen to it withtween.on('active').Tween.COMPLETE_EVENTis a new event that is dispatched when a tween completes or is stopped. Listen to it withtween.on('complete').Tween.LOOP_EVENTis a new event that is dispatched when a tween loops, after any loop delay expires. Listen to it withtween.on('loop').Tween.REPEAT_EVENTis a new event that is dispatched when a tween property repeats, after any repeat delay expires. Listen to it withtween.on('repeat').Tween.START_EVENTis a new event that is dispatched when a tween starts. Listen to it withtween.on('start').Tween.UPDATE_EVENTis a new event that is dispatched when a tween property updates. Listen to it withtween.on('update').Tween.YOYO_EVENTis a new event that is dispatched when a tween property yoyos, after any hold delay expires. Listen to it withtween.on('yoyo').Tween.onActiveis 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.onStartis 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 theonActivecallback. Fix #3330 (thanks @wtravO)Tween.seekhas 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
fromandtovalues 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
startandtovalues 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,fromandtovalues 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.hasStartedis 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.startDelayis 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 theonStartcallback is invoked.Tween.initandTween.playhave 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.onLoopwill now be invoked after theloopDelayhas expired, if any was set.Tween.onRepeatwill now be invoked after therepeatDelayhas expired, if any was set.easeParamswould be ignored for tweens that didn't use a string for the ease function name. Fix #3826 (thanks @SBCGames)- You can now specify
easeParamsfor any custom easing function you wish to use. Fix #3826 (thanks @SBCGames) - All changes to
Tween.stateare now set before any events or callbacks, allowing you to modify the state of the Tween in those handlers (thanks @Cudabear) Tween.dispatchTweenEventis 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.dispatchTweenDataEventis 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.isSeekingis a new internal boolean flag that is used to keep track of the seek progress of a Tween.Timeline.onLoopwill now be invoked after theloopDelayhas expired, if any was set.Timeline.onCompletewill now be invoked after thecompleteDelayhas expired, if any was set.- All changes to
Timeline.stateare now set before any events or callbacks, allowing you to modify the state of the Timeline in those handlers. - The
TIMELINE_LOOP_EVENThas had theloopCounterargument 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
currentproperty to be exactly eitherstartorenddepending on playback direction. - When a TweenData completes it will set the exact
startorendvalue into the target property. TweenDatahas a new function signature, with the newindexandgetActivearguments added to it.TweenBuilderhas been updated to set these, but if you create any TweenData objects directly, use the new signature.TweenData.getActiveValueis 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 asback, and omit the 'ease' part of the direction, such asback.inorback.inout.- The signature of
getStartandgetEndcustom 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
delayandrepeat) 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.createwouldn't start whenTween.playwas 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
renderToTextureenabled on it would cause the object to be vertically flipped. It now renders correctly in both cases. Fix #4647 (thanks @probt)
New Features
Shader.setRenderToTextureis 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.setSampler2DBufferis 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.renderToTextureis a new property flag that is set if you set the Shader to render to a texture.Shader.framebufferis a new property that contains a WebGLFramebuffer reference which is set if you set the Shader to render to a texture.Shader.glTextureis a new property that contains a WebGLTexture reference which is set if you set the Shader to render to a texture.Shader.textureis a new property that contains a Phaser Texture reference which is set if you set the Shader to save to the Texture Manager.TextureManager.addGLTextureis a new method that allows you to add a WebGLTexture directly into the Texture Manager, saved under the given key.TextureSource.isGLTextureis a new boolean property that reflects if the data backing the underlying Texture Source is a WebGLTexture or not.TextureTintPipeline.batchSpritewill now flip the UV if the TextureSource comes from a GLTexture.Math.ToXYis 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.glTextureis 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 propertyquantityto 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 offrameQuantityandrepeat.Pointer.lockedis 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 functionWebGLSnapshot, 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.snapshotCanvasallows 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.snapshotis 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.snapshotAreais 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.snapshotPixelis a new method that will take extract a single pixel color value from a Render Texture and return it as a Color object.- The
SnapshotStateobject has three new properties:isFramebufferboolean andbufferWidthandbufferHeightintegers. Game.CONTEXT_LOST_EVENTis 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_EVENTis 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.currentTypecontains the type of the Game Object currently being rendered.WebGLRenderer.newTypeis 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.nextTypeMatchis 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.removeGameObjectis 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_CONSTis a new constants object that contains the different types of Geometry Objects, such asRECTANGLEandCIRCLE.Circle.typeis a new property containing the shapes geometry type, which can be used for quick type comparisons.Ellipse.typeis a new property containing the shapes geometry type, which can be used for quick type comparisons.Line.typeis a new property containing the shapes geometry type, which can be used for quick type comparisons.Point.typeis a new property containing the shapes geometry type, which can be used for quick type comparisons.Polygon.typeis a new property containing the shapes geometry type, which can be used for quick type comparisons.Rectangle.typeis a new property containing the shapes geometry type, which can be used for quick type comparisons.Triangle.typeis a new property containing the shapes geometry type, which can be used for quick type comparisons.InputPlugin.enableDebugis 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.removeDebugwill remove a Debug Input Shape from the given Game Object and destroy it.Pointer.updateWorldPointis a new method that takes a Camera and then updates the PointersworldXandworldYvalues based on the cameras transform (thanks @Nick-lab)ScaleManager._resetZoomis a new internal flag that is set when the game zoom factor changes.Texture.removeis a new method that allows you to remove a Frame from a Texture based on its name. Fix #4460 (thanks @BigZaphod)
Updates
- When calling
setHitAreaand not providing a shape (i.e. a texture based hit area), it will now setcustomHitAreatofalseby 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.onPointerLockChangeis a new method that handles pointer lock change events and dispatches the lock event.CanvasTexturehas been added to theTexturesnamespace so it can be created without needing to import it. The correct way to create aCanvasTextureis via the Texture Manager, but you can now do it directly if required. Fix #4651 (thanks @Jugacu)- The
SmoothedKeyControlminimum 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.lostContextCallbacksand theonContextLostmethod have been removed. Please use the newCONTEXT_LOSTevent instead.WebGLRenderer.restoredContextCallbacksand theonContextRestoredmethod have been removed. Please use the newCONTEXT_RESTOREDevent instead.TextureManager.getBase64will now emit a console warning if you try to get a base64 from a non-image based texture, such as a WebGL Texture.- The
WebAudioSoundManagerwill now remove the document touch handlers even if the Promise fails, preventing it from throwing a rejection handler error. GameObjectFactory.removeis a new static function that will remove a custom Game Object factory type.GameObjectCreator.removeis a new static function that will remove a custom Game Object creator type.CanvasTexture.getPixelsnow 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.CreateDOMContainerwill now usediv.style.cssTextto set the inline styles of the container, so it now works on IE11. Fix #4674 (thanks @DanLiamco)TransformMatrix.rotationnow returns the properly normalized rotation value.PhysicsEditorParserhas now been exposed under thePhaser.Physics.Matternamespace, so you can call methods on it directly.- Calling
CanvasTexture.updatewill now automatically callrefreshif running under WebGL. This happens for bothdrawanddrawFrame, meaning you no longer need to remember to callrefreshafter drawing to a Canvas Texture in WebGL, keeping it consistent with the Canvas renderer. Frame.destroywill 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
alphaproperty, 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.renderDebugwas calling out-dated Graphics API methods, which would cause the debug to fail (thanks @Fabadiculous)- The
Matter.Factory.constraint,jointandworldConstraintmethods 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.getDurationwould 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.upTimeandPointer.moveTimewould be set to NaN on mobile browsers where Touch.timeStamp didn't exist. Fix #4612 (thanks @BobtheUltimateProgrammer)WebGLRenderer.setScissorwill default thedrawingBufferHeightif no argument is provided, stopping NaN scissor heights.- If you called
Scene.destroywithin a Game Objectpointerdownorpointeruphandler, 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 / CircleGame 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.createFromObjectswould ignore thesceneargument 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
flipXorflipYvalue 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 therepeatCounterproperly, causing Sprite bound animation instances to fail to change their repeat rate. Fix #4553 (thanks @SavedByZero) - The
UpdateList.removemethod 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.destroywill now no longer run its destroy sequence again if it has already been run once. Fix #4634 (thanks @CipSoft-Components)StaticTilemapLayer.destroywill now no longer run its destroy sequence again if it has already been run once.Shader.uniformsnow 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_CHANGEevent is now dispatched by the Input Manager again. - The
Pointer.movementXandPointer.movementYproperties 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.velocityandPointer.midPointvalues are now updated every frame. Based on themotionFactorsetting 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
DESTROYevent hook wasn't removed from Group children when destroying the Group anddestroyChildrenwas 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.updateDisplayOriginno 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.resetCursorwill 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.preRenderdidn't get thetimeproperty correctly, causing input plugin methods that relied on it to fail.KeyboardPlugin.timewasn't being set to the correct value, causingcheckDownto 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_WHEELis a new event dispatched by the Input Plugin allowing you to listen for global wheel events.GAMEOBJECT_WHEELis 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_WHEELis a new event dispatched by a Game Object allowing you to listen for wheel events specifically on that Game Object.Pointer.deltaXis a new property that holds the horizontal scroll amount that occurred due to the user moving a mouse wheel or similar input device.Pointer.deltaYis a new property that holds the vertical scroll amount that occurred due to the user moving a mouse wheel or similar input device.Pointer.deltaZis 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.wheelis a new internal method that handles the wheel event.InputManager.onMouseWheelis a new internal method that handles processing the wheel event.InputManager.processWheelEventis a new internal method that handles processing the wheel event sent by the Input Manager.
Button Released Support
Pointer.buttonis a new property that indicates which button was pressed, or released, on the pointer during the most recent event. It is only set duringupanddownevents and is always 0 for Touch inputs.Pointer.leftButtonReleasedis a new method that returnstrueif it was the left mouse button that was just released. This can be checked in apointerupevent handler to find out which button was released.Pointer.rightButtonReleasedis a new method that returnstrueif it was the right mouse button that was just released. This can be checked in apointerupevent handler to find out which button was released (thanks @BobtheUltimateProgrammer)Pointer.middleButtonReleasedis a new method that returnstrueif it was the middle mouse button that was just released. This can be checked in apointerupevent handler to find out which button was released.Pointer.backButtonReleasedis a new method that returnstrueif it was the back mouse button that was just released. This can be checked in apointerupevent handler to find out which button was released.Pointer.forwardButtonReleasedis a new method that returnstrueif it was the forward mouse button that was just released. This can be checked in apointerupevent 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
pointerupto 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
inputWindowEventsis 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
dragXanddragYvalues sent to thedragcallback 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
inputQueueGame config property. - Removed the
useQueue,queueand_updatedThisFrameproperties from the Input Manager. - Removed the
legacyUpdateandupdatemethods from the Input Manager. - Removed the
ignoreEventsproperty as this should now be handled on a per-event basis. - The Input Manager no longer listens for the
GameEvents.POST_STEPevent. - The following Input Manager methods are no longer required so have been removed:
startPointer,updatePointer,stopPointerandcancelPointer.
As a result, all of the following Input Manager methods have been renamed:
queueTouchStartis now calledonTouchStartand invoked by the Touch Manager.queueTouchMoveis now calledonTouchMoveand invoked by the Touch Manager.queueTouchEndis now calledonTouchEndand invoked by the Touch Manager.queueTouchCancelis now calledonTouchCanceland invoked by the Touch Manager.queueMouseDownis now calledonMouseDownand invoked by the Mouse Manager.queueMouseMoveis now calledonMouseMoveand invoked by the Mouse Manager.queueMouseUpis now calledonMouseUpand 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,_hasDownCallbackand_hasMoveCallbackproperties from the Input Manager - Removed the
processDomCallbacks,addDownCallback,addUpCallback,addMoveCallback,domCallbacks,addDownCallback,addUpCallbackandaddMoveCallbackmethods.
Also, CSS cursors can now be set directly:
- Cursors are now set and reset immediately on the canvas, leading to the removal of
_setCursorand_customCursorproperties.
The following changes took place in the Input Plugin class:
- The method
processDragEventshas been removed as it's now split across smaller, more explicit methods. processDragDownEventis a new method that handles a down event for drag enabled Game Objects.processDragMoveEventis a new method that handles a move event for drag enabled Game Objects.processDragUpEventis a new method that handles an up event for drag enabled Game Objects.processDragStartListis a new internal method that builds a drag list for a pointer.processDragThresholdEventis a new internal method that tests when a pointer with drag thresholds can drag.processOverEventsis a new internal method that handles when a touch pointer starts and checks for over events.processOutEventsis 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.dirtyhas been removed as it's no longer required.Pointer.justDownhas been removed as it's not used internally and makes no sense under the DOM event system.Pointer.justUphas been removed as it's not used internally and makes no sense under the DOM event system.Pointer.justMovedhas been removed as it's not used internally and makes no sense under the DOM event system.- The
Pointer.resetmethod has been removed as it's no longer required internally. Pointer.touchstartnow has two arguments, the Touch List entry and the Touch Event. The full Touch Event is now stored inPointer.event(instead of the Touch List entry).Pointer.touchmovenow has two arguments, the Touch List entry and the Touch Event. The full Touch Event is now stored inPointer.event(instead of the Touch List entry).Pointer.touchendnow has two arguments, the Touch List entry and the Touch Event. The full Touch Event is now stored inPointer.event(instead of the Touch List entry).Pointer.touchcancelnow has two arguments, the Touch List entry and the Touch Event. The full Touch Event is now stored inPointer.event(instead of the Touch List entry).
New Features
Matter.Factory.velocityis a new method that allows you to set the velocity on a Matter Body directly.Matter.Factory.angularVelocityis a new method that allows you to set the angular velocity on a Matter Body directly.Matter.Factory.forceis a new method that allows you to apply a force from a world position on a Matter Body directly.GetBounds.getTopCenteris a new method that will return the top-center point from the bounds of a Game Object.GetBounds.getBottomCenteris a new method that will return the bottom-center point from the bounds of a Game Object.GetBounds.getLeftCenteris a new method that will return the left-center point from the bounds of a Game Object.GetBounds.getRightCenteris 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
desynchronizedtotrue(the default isfalse). For more details about what this means see https://developers.google.com/web/updates/2019/05/desynchronized. - The CanvasRenderer can now use the
transparentGame Config property in order to tell the browser an opaque background is in use, leading to faster rendering in a 2D context. GameObject.scaleis 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 thesetScalemethod. This is handy for uniformly scaling objects via tweens, for example.Base64ToArrayBufferis 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.ArrayBufferToBase64is a new utility function that converts an ArrayBuffer into a base64 string. You can also optionally included a media type, such asimage/jpegwhich will result in a data uri being returned instead of a plain base64 string. *WebAudioSoundManager.decodeAudiois 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#DECODEDis a new event emitted by the Web Audio Sound Manager when it has finished decoding audio data.Phaser.Sound.Events#DECODED_ALLis a new event emitted by the Web Audio Sound Manager when it has finished decoding all of the audio data files passed to thedecodeAudiomethod.Phaser.Utils.Objects.Pickis 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.alignandText.setAligncan now acceptjustifyas 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_STEPis 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
Zoneswill now use the newcustomHitAreaproperty introduced in 3.17 to avoid their hit areas from being resized if you specified your own custom hit area (thanks @rexrainbow)- The default
BaseShadervertex shader has a new uniformuResolutionwhich is set during the Shader init and load to be the size of the Game Object to which the shader is bound. - The default
BaseShadervertex shader will now set thefragCoordvarying 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
DOMElementCSSRendererfile that causedgetBoundingClientRectto be called every render. This has been removed, which increases performance significantly for DOM heavy games. - The
TimeStepwill no longer set itsframeproperty to zero in theresetDeltamethod. Instead, this property is incremented every step, no matter what, giving an accurate indication of exactly which frame something happened on internally. - The
TimeStep.stepmethod 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.nowis a new property that holds the exactperformance.nowvalue, as set at the start of the current game step.Matter.Factory.fromVerticescan now take a vertices path string as itsvertexSetsargument, as well as an array of vertices.GetBounds.prepareBoundsOutputis 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.defaultStrokeWidthto drawn the body with, this makes static bodies consistent with dynamic ones (thanks @samme) Group.nameis 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.setGameSizewill now adjust the size of the canvas element as well. Fix #4482 (thanks @sudhirquestai) Scale.Events.RESIZEnow sends two new arguments to the handler:previousWidthandpreviousHeight. 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
onSizewhich is invoked by handling the Scale ManagerRESIZEevent. 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 callthis.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.translatehas been renamed toGraphics.translateCanvasto make it clearer what it's actually translating (i.e. the drawing buffer, not the Graphics object itself)Graphics.scalehas been renamed toGraphics.scaleCanvasto make it clearer what it's actually scaling (i.e. the drawing buffer, not the Graphics object itself)Graphics.rotatehas been renamed toGraphics.rotateCanvasto make it clearer what it's actually rotating (i.e. the drawing buffer, not the Graphics object itself)- The
widthandheightof an Arc / Circle Shape Game Object is now set to be the diameter of the arc, not the radius (thanks @rexrainbow) LineStyleCanvasnow takes analtColorargument which is used to override the context color.LineStyleCanvasnow takes analtAlphaargument which is used to override the context alpha.FillStyleCanvasnow takes analtAlphaargument which is used to override the context alpha.StaticPhysicsGroupcan now take aclassTypeproperty in its Group Config and will use the value of it, rather than override it. If none is provided it'll default toArcadeSprite. Fix #4401 (thanks @Legomite)Phaser.Tilemaps.Parsers.Tiledused to run the static functionParseJSONTiled.Parsers.Tiledis now just a namespace, so access the function within it:Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiled.Phaser.Tilemaps.Parsers.Impactused to run the static functionParseWeltmeister.Parsers.Impactis now just a namespace, so access the function within it:Phaser.Tilemaps.Parsers.Impact.ParseWeltmeister.Phaser.Tilemaps.Parsers.Tiled.AssignTilePropertiesis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Tiled.Base64Decodeis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Tiled.BuildTilesetIndexis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Tiled.ParseGIDis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Tiled.ParseImageLayersis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Tiled.ParseJSONTiledis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Tiled.ParseObjectis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Tiled.ParseObjectLayersis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Tiled.ParseTileLayersis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Tiled.ParseTilesetsis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Tiled.ParseTilesetsis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Impact.ParseTileLayersis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Impact.ParseTilesetsis now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Impact.ParseWeltmeisteris now a public static function, available to be called directly.Phaser.Tilemaps.Parsers.Tiled.Pickhas been removed. It is now available underPhaser.Utils.Objects.Pick, which is a more logical place for it.- You can now call
this.scene.removeat the end of a Scene'screatemethod 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.setSizearguments 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.getParentRotationis 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.restartnow sets the Tween propertieselapsed,progress,totalElapsedandtotalProgressto zero when called, rather than adding to existing values should the tween already be running.ArcadePhysics.Body.resetFlagsis a new method that prepares the Body for a physics step by resetting thewasTouching,touchingandblockedstates.ArcadePhysics.Body.preUpdatehas two new argumentswillStepanddelta. IfwillStepis true then the body will call resetFlags, sync with the parent Game Object and then run one iteration ofBody.update, using the provided delta. If false, only the Game Object sync takes place.ArcadePhysics.World.updatewill now determine if a physics step is going to happen this frame or not. If not, it no longer callsWorld.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) thenWorld.stepis called accordingly.ArcadePhysics.World.postUpdatewill no longer callBody.postUpdateon all of the bodies if no World step has taken place this frame.ArcadePhysics.World.stepwill now increment thestepsLastFramecounter, allowingpostUpdateto 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
separateCirclefunction would cause the position to be setNaN(thanks @hizzd) - The
CameraManagerwould incorrectly destroy thedefaultCamera 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 thedestroymethod. Fix #4520 (thanks @telinc1) - Passing a Frame object to
Bob.setFramewould 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.getTimewould returnNaNbecause it incorrectly accessed the time value from the TimeStep.- Text with a
fixedWidthorfixedHeightcould cause the canvas to be cropped if less than the size of the Text itself (thanks @rexrainbow) - Changing the
radiusof 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
paddingin a Text style configuration object would cause an error about calling split on undefined. Padding can now be applied both in the config and viasetPadding. Tilemap.createBlankDynamicLayerwould 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.createDynamicLayerwould fail if you called it without setting thexandyarguments, even though they were flagged as being optional. Fix #4508 (thanks @jackfreak)RenderTexture.drawdidn't work if noxandyarguments 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 likeRenderTexture.erasenot working with Groups. Fix #4528 (thanks @jbgomez21 @telinc1)- The
GridGame Object wouldn't render in Canvas mode at all. Fix #4585 (thanks @fyyyyy) - If you had a
Graphicsobject in the display list immediately after an object with a Bitmap Mask it would throw an errorUncaught TypeError: Cannot set property 'TL' of undefined. Fix #4581 (thanks @Petah @Loonride) - Calling Arcade Physics
Body.reseton a Game Object that doesn't have any bounds, like a Container, would throw an error about being unable to accessgetTopLeft. If this is the case, it will now set the position to the given x/y values (thanks Jazz) - All of the
Tilemaps.Parsers.Tiledstatic functions are now available to be called directly. Fix #4318 (thanks @jestarray) Arcade.StaticBody.setSizenow centers the body correctly, as with the other similar methods. Fix #4213 (thanks @samme)- Setting
random: falsein a Particle Emitter config option no longer causes it to think random is true (thanks @samme) Zone.setSizedidn't update the displayOrigin, causing touch events to be inaccurate as the origin was out. Fix #4131 (thanks @rexrainbow)Tween.restartwouldn'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.setTimeScalewould 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.BaseShaderis 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 newShaderGame Objects. They are stored in the Shader cache.- The Shader Cache
this.cache.shaderhas been updated. Rather than holding plain text fragments, it now holds instances of the newBaseShaderobjects. As a result, usingcache.shader.get(key)will now return aBaseShaderinstead of a text file. - The
GLSLFileloader 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 aBaseShaderinstance in the shader cache. - The
GLSLFileloader 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.setMaskis 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 theCamera.maskproperty.Camera.clearMaskis a new method that clears a previously set mask on a Camera.- There is a new Game Config property
input.windowEventswhich 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 likePOINTER_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.setInvertAlphais a new method that allows you to set theinvertAlphaproperty 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.maskCountis a new internal property that tracks the number of masks in the stack.WebGLRenderer.maskStackis a new internal array that contains the current mask stack.
Arcade Physics
New Features
overlapTilesis 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 viathis.physics.overlapTilesand the World instance.collideTilesis 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 viathis.physics.collideTilesand the World instance.overlapRectis 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.setCollideWorldBoundsmethod has two new optional argumentsbounceXandbounceYwhich, if given, will set the World Bounce values for the body.
Updates
Body.preUpdateis 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.updatehas 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.postUpdatehas 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.lateSet has been removed and is no longer populated, as it's no longer required. World.updatenow callsBody.preUpdatejust once per game step, then callsBody.updateas many times as is required as per the FPS setting, and no longer callsBody.postUpdateat all.World.collideSpriteVsTilemapLayernow returns a boolean if a collision or overlap happens, where-as before it didn't.World.collideSpriteVsTilemapLayerHandleris a new private method that handles all tilemap collision checks.- The internal method
SeparateTilenow has a new argumentisLayerwhich controls if the set comes from a layer or an array. - The internal method
TileCheckXnow has a new argumentisLayerwhich controls if the set comes from a layer or an array. - The internal method
TileCheckYnow has a new argumentisLayerwhich controls if the set comes from a layer or an array. Body.isMovinghas been removed as it was never used internally.Body.stopVelocityOnCollidehas been removed as it was never used internally.- All of the Arcade Physics Components are now available directly under the
Phaser.Physics.Arcade.Componentsnamespace. Fix #4440 (thanks @jackfreak) Phaser.Physics.Arcade.Eventsis now exposed in the namespace, preventing it from erroring if you use them in TypeScript. Fix #4481 (thanks @danielalves)- The Matter World configuration value
bodyDebugFillColorhas been renamed todebugBodyFillColorto be consistent with the rest of the options. - The Matter World configuration has a new property:
debugStaticBodyColorthat sets the static body debug color.
Bug Fixes
- The
Body.deltavalues 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 callthis.physics.collideduring a Sceneupdateand it will work properly again. Fix #4370 (thanks @NokFrt) ArcadePhysics.furthestnow iterates the bodies Set, rather than the RTree, which keeps it working even if the RTree has been disabled.ArcadePhysics.closestnow iterates the bodies Set, rather than the RTree, which keeps it working even if the RTree has been disabled.Body.setVelocitycaused thespeedproperty to be set toNaNif you didn't provide ayargument.- Passing an array of configuration objects to
physics.add.groupwould ignore them and none of the children would be assigned a physics body. Fix #4511 (thanks @rgk) - A Body with
dampinganddragenabled would fail to move if it went from zero velocity to a new velocity inside anupdateloop. It will now reset its speed accordingly and retain its new velocity (thanks StealthGary)
Facebook Instant Games Plugin
- The method
consumePurchaseshas been renamed toconsumePurchaseto bring it in-line with the Facebook API. getProductis 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
CREATEevent after it has been created by the Scene Manager. If the Scene has acreatemethod this event comes after that, so is useful to knowing when a Scene may have finished creating Game Objects, etc. (thanks @jackfreak) Tilemap.removeTileis 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.removeis a new method that immediately removes the given Tween from all of its internal arrays.Tween.removeis 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.isPausedis a new method that will return if the given Scene is currently paused or not (thanks @samme)ScenePlugin.isPausedis a new method that will return if the given Scene is currently paused or not (thanks @samme)TextureManager.removeKeyis a new method that will remove a key from the Texture Manager without destroying the texture itself.Matter.World.resetCollisionIDsis 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
keyandframe. This allows you to create a RenderTexture pre-populated with the size and frame from an existing texture (thanks @TadejZupancic) GameObjects.Components.PathFolloweris 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.removeLayeris a new method that allows you to remove a specific layer from a Tilemap without destroying it.Tilemap.destroyLayeris a new method that allows you to destroy a layer and remove it from a Tilemap.Tilemap.renderDebugFullis a new method that will debug render all layers in the Tilemap to the given Graphics object.Geom.Intersects.GetCircleToCircleis a new function that will return the point/s of intersection between two circles (thanks @florianvazelle)Geom.Intersects.GetCircleToRectangleis a new function that will return the point/s of intersection between a circle and a rectangle (thanks @florianvazelle)Geom.Intersects.GetLineToCircleis a new function that will return the point/s of intersection between a line and a circle (thanks @florianvazelle)Geom.Intersects.GetLineToRectangleis a new function that will return the point/s of intersection between a line and a rectangle (thanks @florianvazelle)Geom.Intersects.GetRectangleToRectangleis a new function that will return the point/s of intersection between two rectangles (thanks @florianvazelle)Geom.Intersects.GetRectangleToTriangleis a new function that will return the point/s of intersection between a rectangle and a triangle (thanks @florianvazelle)Geom.Intersects.GetTriangleToCircleis a new function that will return the point/s of intersection between a triangle and a circle (thanks @florianvazelle)Geom.Intersects.GetTriangleToLineis a new function that will return the point/s of intersection between a triangle and a line (thanks @florianvazelle)Geom.Intersects.GetTriangleToTriangleis a new function that will return the point/s of intersection between two triangles (thanks @florianvazelle)Size.setCSSis a new method that will set the Size components width and height to the respective CSS style properties of the given element.CSSFileis a new Loader FileType that allows you to load css into the current document via the normal Phaser Loader, using theload.cssmethod. 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.MultiScriptFileis a new Loader FileType that allows you to load multiple script files into the document via the Phaser Loader, using the newload.scriptsmethod. The difference between this andload.scriptis 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.getDurationis 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.setScrollFactormethod has a new optional argumentupdateChildren. If set, it will change thescrollFactorvalues of all the Container children as well as the Container. Fix #4466 #4475 (thanks @pinkkis @enriqueto) - There is a new webpack config
FEATURE_SOUNDwhich is set totrueby default, but if set tofalseit will exclude the Sound Manager and all of its systems from the build files. Fix #4428 (thanks @goldfire) Scene.Systems.rendereris a new property that is a reference to the current renderer the game is using.Utils.Objects.SetValueis 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.glFuncMapis a new object, populated during theinitmethod, that contains uniform mappings from key to the corresponding gl function, i.e.mat2togl.uniformMatrix2fv.BaseCache.getKeysis 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.generateFrameNumberscan now accept a start number greater than the end number, and will generate them in reverse (thanks @cruzdanilo)- The return from the
ScenePlugin.addmethod 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 otheraddmethods in the API. Fix #4359 (thanks @BigZaphod) - The
PluginManager.installScenePluginmethod has a new optional boolean parameterfromLoaderwhich 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_FAILEDwhich is fired if you try to enter fullscreen mode, but the browser rejects it for some reason. - The
ScaleModeComponent has been removed from every Game Object, and along with it thescaleModeproperty andsetScaleModemethod. 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.nowproperty value is now synced to be theTimeStep.timevalue when the Clock plugin boots and is no longerDate.now()until the first update (thanks @Antriel) Graphics.strokePointshas renamed the second argument fromautoClosetocloseShape. There is also a new third argumentclosePath, which defaults totrueand automatically closes the path before stroking it. TheendIndexargument is now the fourth argument, instead of the third.Graphics.fillPointshas renamed the second argument fromautoClosetocloseShape. There is also a new third argumentclosePath, which defaults totrueand automatically closes the path before filling it. TheendIndexargument is now the fourth argument, instead of the third.- Calling
Texture.destroywill now callTextureManager.removeKeyto ensure the key is removed from the manager, should you destroy a texture directly, rather than going viaTextureManager.remove. Fix #4461 (thanks @BigZaphod) SpriteSheetFromAtlasnow adds in a__BASEentry for the Sprite Sheet it creates, keeping it consistent with the other frame parsers (thanks @Cirras)- The
fromandtoproperties in the PathFollower Config can now be used to set the span of the follow duration (thanks @kensleebos) Graphics.lineFxToandGraphics.moveFxTohave 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.infiniteis a new boolean that controls if the map data is infinite or not.DynamicTilemapLayer.destroywill now remove the layer from the Tilemap it belongs to, clearing it from the layers array. Fix #4319 (thanks @APXEOLOG)StaticTilemapLayer.destroywill now remove the layer from the Tilemap it belongs to, clearing it from the layers array. Fix #4319 (thanks @APXEOLOG)DynamicTilemapLayer.destroyhas a new optional boolean argumentremoveFromTilemapwhich will control if the layer is removed from the parent map or not.StaticTilemapLayer.destroyhas a new optional boolean argumentremoveFromTilemapwhich will control if the layer is removed from the parent map or not.Tilemap.copynow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.fillnow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.forEachTilenow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.putTilesAtnow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.randomizenow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.calculateFacesAtnow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.renderDebugnow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.replaceByIndexnow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.setCollisionnow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.setCollisionBetweennow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.setCollisionByPropertynow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.setCollisionByExclusionnow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.setCollisionFromCollisionGroupnow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.setTileIndexCallbacknow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.setTileLocationCallbacknow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.shufflenow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.swapByIndexnow actually returnsnullif an invalid layer was given, as per the docs.Tilemap.weightedRandomizenow actually returnsnullif an invalid layer was given, as per the docs.BaseCamera.cameraManageris a new property that is a reference to the Camera Manager, set in thesetScenemethod.CameraManager.defaultis 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
GraphicsGame Object now has 3 new Transform Matrix instances called_tempMatrix1to_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
Keymethod 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 newKey.pluginproperty, and cleared indestroy. KeyboardPlugin.removeKeyhas a new optional argumentdestroythat will, if set, destroy the Key object being removed from the plugin.InteractiveObject.customHitAreais 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).
ParseXMLBitmapFonthas now been exposed as a static function on theBitmapTextobject, 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)
GetAdvancedValuenow uses the correct Math RND reference, which means anything that used therandIntorrandFloatfeatures 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
pointeruphandler, and notpointerdown. 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.Spreadwould only use theminvalue to work out the step value but not apply it to the property being set (thanks @galman33)- Calling
Tween.pausereturns the Tween instance, however, if it was already paused, it would returnundefined, causing problems when chaining Tween methods (thanks @kyranet) - Calling
TweenManager.makeActivereturns the TweenManager instance, however, if you create a tween externally and callmakeActivewith it, this would returnundefined. - Setting the
fixedWidthand / orfixedHeightproperties in the configuration of aTextwould be ignored, they were only supported when calling thesetFixedSizemethod. 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.Addwould 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.getCenterXandTile.getCenterYwould return the wrong values for tiles on scaled layers. Fix #3845 (thanks @oloflarsson @florianvazelle)Camera.startFollowwill now ensure that if the Camera is using bounds that thescrollXandscrollYvalues set after first following the Game Object do not exceed the bounds (thanks @snowbillr)- Creating a Tween with a
durationof zero would cause the tweened object properties to be set toNaN. 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.stopassumed 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.restartmultiple times in a row would cause the tween to freeze. It will now disregard all additional calls torestartif it's already in a pending state (thanks @rgk) - Tween Timelines would only apply the
delayvalue of a child tween once and not on loop. Fix #3841 (thanks @Edwin222 @Antriel) Texture.addwill 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 returnnullinstead of a Frame object, and theframeTotalwill 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.playon a tween that had already finished and was pending removal will stop the tween from getting stuck in anisPlayingstate and will restart the tween again from the beginning. Callingplayon 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.updatemethod is now called every frame, as long as a native DOM event hasn't already fired it, which allows things likesetPollRateto work again. Fix #4405 (thanks @Shucki) Pointer.getDurationwould 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.UpDurationhas been changed so thedurationbeing checked is now against the current game clock. This means you can use it to check if a Key was released withindurationms ago, based on the time now, not the historic value of the Key.Keyboard.DownDurationhas been changed so thedurationbeing 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
hitAreaif 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.clearRenderToTexturewill 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
pointerupevent handler on a touch device will no longer causeUncaught 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.clearhas a new argumentskipQueuewhich is used to avoid clearing a Game Object twice. This, combined with the fix for 4463 means you will no longer get aCannot read property 'dragState'error if you destroy a Game Object enabled for drag where another draggable object exists. Fix #4228 (thanks @YannCaron)UpdateList.removewill now move the removed child to the internal_pendingRemovalarray, 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
pixelPerfectwhen 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
fixedWidthandfixedHeighton 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_STARTwhich 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
DRAGwhich 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_ENDwhich is emitted by a Pointer Constraint when it stops dragging a body. Listen for this event from the Matter World instance. - The
cameraproperty 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. bodyis a new property that holds a reference to the Body being dragged, if any.partis a new property that holds a reference to the Body part that was clicked on which started the drag.- The internal
getBodyPartmethod has been renamed tohitTestBodyto more accurately reflect what it does. - The class no longer listens for the pointer
upevent, instead of tracks the active pointer and waits for that to be released. This has reduced the complexity and size of theupdatemethod considerably. stopDragis 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.setTileScalehas been updated so that theyargument is optional and set to match thexargument, likesetScaleelsewhere in the API.InputManager.timeis a new property that holds the most recent time it was updated from the Game step, which plugins can access.InputManager.preStepis a new method that populates some internal properties every step.KeyboardPlugin.timehas moved from being a property to being a getter, which returns the time from the InputManager.- The
scaleproperty has been added to theSceneclass (thanks @strangeweekend) Matter.World.removenow uses theComposite.removemethod internally. Previously, it usedComposite.removeBodywhich 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_OUTevent if they leave the game (i.e. are released), where-as before they would only trigger thePOINTER_UPevent. Now, both happen (thanks @rgk)
Bug Fixes
- The
Mesh.setAlphamethod 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.checkDownwould always fail if using the new event system, because the time value it was checking wasn't updated.- Entering
Fullscreenmode 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_OUTevent 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 theInputManager._emitIsOverEventproperty 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.setBlendModemethod 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.Bootnamespace has been renamed toPhaser.Core. As a result, thebootfolder has been renamed tocore. This impacts theTimeStepclass andVisibilityHandlerfunction, which have been moved to be under the new namespace. - The
Phaser.Animationsnamespace was incorrectly exposed in the Phaser entrypoints asAnimation(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 fromPhaser.AnimationtoPhaser.Animations, i.e.Phaser.Animation.AnimationFrametoPhaser.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_tochangedata-to keep it consistent with other keyed events. Note the change from_to-. - The Keyboard Plugin
keydowndynamic event string has changed fromkeydown_tokeydown-to keep it consistent with other keyed events. Note the change from_to-. - The Keyboard Plugin
keyupdynamic event string has changed fromkeyup_tokeyup-to keep it consistent with other keyed events. Note the change from_to-. - The
texturesreadyevent emitted by the Texture Manager has been renamed toready. - The
loadcompleteevent emitted by the Loader Plugin has been renamed topostprocessto be reflect what it's used for. - Game Objects used to emit a
collideevent if they had an Arcade Physics Body withonCollideset, that collided with a Tile. This has changed. The event has been renamed totilecollideand 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
overlapevent if they had an Arcade Physics Body withonOverlapset, that overlapped with a Tile. This has changed. The event has been renamed totileoverlapand 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.SeperateXhas been renamed toSeparateXto correct the spelling mistake. - The function
Phaser.Physics.Impact.SeperateYhas been renamed toSeparateYto correct the spelling mistake. - The
endedevent inWebAudioSoundhas been renamed tocompleteto make it more consistent with the rest of the API. - The
endedevent inHTML5AudioSoundhas been renamed tocompleteto make it more consistent with the rest of the API. - The
Phaser.Utils.Objectsnamespace was incorrectly exposed in the Phaser entrypoints asObject(note the lack of plural), this has now been fixed so all associated functions are properly namespaced. Phaser.GameObjects.Blitter.Bobhas been renamed toPhaser.GameObjects.Bobto avoid namespace conflicts in TypeScript.Phaser.GameObjects.Text.TextStylehas been renamed toPhaser.GameObjects.TextStyleto 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.addUpCallbackmethod.InputPlugin.addDownCallbackmethod.InputPlugin.addMoveCallbackmethod.InputManager.queueproperty.InputManager.domCallbacksproperty.InputManager._hasUpCallbackproperty.InputManager._hasDownCallbackproperty.InputManager._hasMoveCallbackproperty.InputManager.processDomCallbacksmethod.InputManager.addUpCallbackmethod.InputManager.addDownCallbackmethod.InputManager.addMoveCallbackmethod.
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_KEYevent name has changed tokeydown-KEY. Note the change from an underscore to a hyphen. - In all cases the
keyup_KEYevent name has changed tokeyup-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.addCaptureis a new method that allows you to define a set of keycodes to have the default browser behaviors disabled on.KeyboardPlugin.removeCaptureis a new method that removes specific previously set key captures.KeyboardPlugin.clearCapturesis a new method that removes all key captures.KeyboardPlugin.getCapturesis a new method that returns an array of all current key captures.KeyboardPlugin.enableGlobalCaptureis a new method that enables any key captures that have been created.KeyboardPlugin.disableGlobalCaptureis a new method that disables any key captures that have been created, without removing them from the captures list.KeyboardPlugin.addKeyhas a new boolean argumentenableCapture, which is true by default, that will add a key capture for the Key being created.KeyboardPlugin.addKeyshas a new boolean argumentenableCapture, 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, theKeyboardPlugindid 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. theKeyboardPluginclass still exists, and is still the main point of interface when you callthis.input.keyboardin 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.capturewhich 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
preventDefaultonly 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.emitOnRepeatis a new boolean property that controls if the Key will continuously emit adownevent while being held down (true), or emit the event just once, on first press, and then skip future events (false).Key.setEmitOnRepeatis a new chainable method for setting theemitOnRepeatproperty.- The
KeyboardPlugin.addKeysmethod has a new optional booleanemitOnRepeatwhich sets that property on all Key objects it creates as part of the call. It defaults tofalse. - The
KeyboardPlugin.addKeymethod has a new optional booleanemitOnRepeatwhich sets that property on the Key object it creates. It defaults tofalse. - The
Keyclass now extends EventEmitter and emits two events directly:downandup. 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_FIREFOXandBRACKET_LEFT_FIREFOX(thanks @wmateam) Key.onDownis a new method that handles the Key being pressed down, including down repeats.Key.onUpis a new method that handles the Key being released.Key.destroyis a new method that handles Key instance destruction. It is called automatically inKeyboardPlugin.destroy.- The
Key.preventDefaultproperty has been removed. This is now handled by the global keyboard capture methods. Key.metaKeyis 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.keyboardis a new property that instantiates the global Keyboard Manager, if enabled in the game config.- The
KeyboardPlugin.addKeymethod has a new boolean propertyenableCapturewhich automatically prevents default on the Key being created. - The
KeyboardPlugin.addKeysmethod has a new boolean propertyenableCapturewhich automatically prevents default on Keys being created. Phaser.Input.Keyboard.ProcessKeyDownhas been removed as it's no longer required,Key.onDownhandles it instead.Phaser.Input.Keyboard.ProcessKeyUphas been removed as it's no longer required,Key.onUphandles it instead.- The Keyboard Manager has a property called
captureswhich is an array of keycodes, as populated by the Game Config. Any key code in the array will havepreventDefaultcalled on it if pressed. KeyboardPlugin.manageris a new property that references the Keyboard Manager and is used internally.KeyboardPlugin.targethas been removed as it's no longer used by the class.KeyboardPlugin.queuehas been removed as it's no longer used by the class.KeyboardPlugin.onKeyHandlerhas been removed as it's no longer used by the class.KeyboardPlugin.startListenershas been removed as it's no longer used by the class.KeyboardPlugin.stopListenershas 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
startListenersmethod. - When enabling a Game Object for input it will now use the
widthandheightproperties 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.smoothFactoris 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.inputSmoothFactoris 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 asinput: { smoothFactor: value }.InputManager.transformPointerhas a new boolean argumentwasMove, which controls if the pointer is being transformed after a move or up/down event.Pointer.velocityis 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 thePointer.motionFactorproperty. 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.angleis 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 thePointer.motionFactorproperty. 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.distanceis 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 thePointer.motionFactorproperty. 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.motionFactoris 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
preUpdateevent, with the capital U, instead ofpreupdate. This has now been corrected. Fix #4185 (thanks @gadelan) Pointer.updateMotionis 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.timeis a new property that holds the time the Pointer was last updated by the Game step.Pointer.getDistancehas 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.getDistanceXis 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.getDistanceYis 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.getDurationis 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.getAngleis 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'sdownXanddownYvalues 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
mousedownlistener for the game canvas and then callwindow.focuswhen detected (assuming the game configautoFocusproperty wastrue). Responsibility for this has now been moved to the Mouse ManageronMouseDownhandler. - In previous versions, the VisibilityHandler would create a
mouseoutlistener for the game canvas and then setgame.isOverwhen detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input ManagerisOverproperty directly. - In previous versions, the VisibilityHandler would create a
mouseoverlistener for the game canvas and then setgame.isOverwhen detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input ManagerisOverproperty directly. - The
Phaser.Game.isOverproperty 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 dothis.input.isOverfrom 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 withthis.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 withthis.input.on('gameout')from within a Scene. - The Game used to emit a
mouseoverevent 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 eventgameover. - The Game used to emit a
mouseoutevent 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 eventgameout. - If the
windowobject exists (which it will in normal browser environments) newmouseupandtouchendevent listeners are bound to it and trigger the normalmouseuportouchendevents within the internal input system. This means you will now get apointerupevent 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
autoFocusgame 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 withthis.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 withthis.input.on('pointerupoutside')from within a Scene. Pointer.downElementis 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.upElementis 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.dragStateproperty has been removed. This is no longer used internally as it has to be tracked per Scene, not on a global level. InputPlugin.setDragStateis a new internal method that sets the drag state for the given Pointer.InputPlugin.getDragStateis 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.leftButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.rightButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.middleButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.backButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.forwardButtonDownwill 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.moveandPointer.downnow useinto check for the existance of thebuttonsproperty 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
zoomto be > 1 then it will automatically enablepixelArtmode, unless you setpixelArt: falsein 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 isfalse(turned off). - The Game Config property
autoResizehas been removed as it's now redundant. - The WebGL and Canvas Renderers no longer change the Canvas size in their
resizemethods. They just update internal properties. - The WebGL and Canvas Renderers now read the
width,heightandresolutionvalues from the Scale Manager, not the Game Config. CameraManager.baseScaleproperty has been removed as it's no longer used anywhere.- The BaseCamera and Camera
preRendermethods now only take a resolution argument and use it internally for their transforms. InputManager.scaleManageris a new property that is a reference to the Scale Manager. This is populated in thebootmethod.- The
InputManager.transformXmethod has been removed. This is now available in the ScaleManager. - The
InputManager.transformYmethod has been removed. This is now available in the ScaleManager. - The
InputManager.scaleproperty has been removed. This is now available in the ScaleManager underdisplayScale. - The
InputManager.resizemethod has been removed as this process is now handled by the ScaleManager. - The
InputManager.boundsproperty has been removed as this process is now handled by the ScaleManager. - The
InputManager.updateBoundsmethod has been removed as this process is now handled by the ScaleManager. - The
InputManager.getOffsetXmethod has been removed as it's no longer required. - The
InputManager.getOffsetYmethod has been removed as it's no longer required. - The
InputManager.getScaleXmethod has been removed as it's no longer required. - The
InputManager.getScaleYmethod has been removed as it's no longer required. - The
SceneManager.resizemethod has been removed as it's no longer required. - The
Scene.Systems.resizemethod has been removed as it's no longer required. - Scenes will no longer dispatch the
resizeevent. You should now listen for this event from the Scale Manager instead. BaseCamera.confighas been removed as it's no longer required.BaseCamera.scaleManageris a new property that references the Scale Manager and is used internally for size checks.- The
Game.resizemethod has been removed as it's no longer required. You should now callScaleManager.resizeinstead. - The Game will no longer dispatch the
resizeevent. You should now listen for this event from the Scale Manager instead.
Facebook Instant Games Updates and Fixes
- Added the
Leaderboard.getConnectedScoresmethod, to get a list of scores from player connected entries. - The
loadPlayerPhotofunction in the Instant Games plugin now listens for the updated Loader event correctly, causing thephotocompleteevent to fire properly. Leaderboard.setScorenow emits the LeaderboardScore object with thesetscoreevent, as the documentation said it did.Leaderboard.getPlayerScorenow only populates theplayerScoreproperty if the entry isn'tnull.- If the
setScoreorgetPlayerScorecalls fail, it will returnnullas the score instance, instead of causing a run-time error. - You can now pass an object or a string to
setScoreand objects will be automatically stringified. - The
preloadAdsmethod will now only create an AdInstance object if the interstitialloadSyncpromise resolves. - The
preloadVideoAdsmethod will now only create an AdInstance object if the interstitialloadSyncpromise resolves. - The
preloadAdsmethod will now emit theadsnofillevent, if there are no ads in the inventory to load. - The
preloadVideoAdsmethod will now emit theadsnofillevent, if there are no ads in the inventory to load. - The
showAdmethod will now emit theadsnotloadedevent, if there are no ads loaded matching the given Placement ID. - The
showVideomethod will now emit theadsnotloadedevent, if there are no ads loaded matching the given Placement ID. - Showing an ad will emit the
adfinishedevent when the ad is closed, previously this event was calledshowadbut the new name better reflects what has happened. - The Facebook Plugin is now available in the
Phaser.Sceneclass template under thefacebookproperty (thanks @bryanwood) - Fixed the
Leaderboard.getScoresmethod to now take the arguments into account. Fix #4271 (thanks @Oramy) - Fixed an API validation error in the
chooseContextmethod. Fix #4248 (thanks @yadurajiv)
New Features
- You can now load external Scene files using the new
load.sceneFilemethod. 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
setStatewhich will set the state property in a chainable call. BlendModes.ERASEis 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_INis a new Canvas-only blend mode that allows you to use thesource-incomposite operation when rendering Game Objects.BlendModes.SOURCE_OUTis a new Canvas-only blend mode that allows you to use thesource-outcomposite operation when rendering Game Objects.BlendModes.SOURCE_ATOPis a new Canvas-only blend mode that allows you to use thesource-atopcomposite operation when rendering Game Objects.BlendModes.DESTINATION_OVERis a new Canvas-only blend mode that allows you to use thedestination-overcomposite operation when rendering Game Objects.BlendModes.DESTINATION_INis a new Canvas-only blend mode that allows you to use thedestination-incomposite operation when rendering Game Objects.BlendModes.DESTINATION_OUTis a new Canvas-only blend mode that allows you to use thedestination-outcomposite operation when rendering Game Objects.BlendModes.DESTINATION_ATOPis a new Canvas-only blend mode that allows you to use thedestination-atopcomposite operation when rendering Game Objects.BlendModes.LIGHTERis a new Canvas-only blend mode that allows you to use thelightercomposite operation when rendering Game Objects.BlendModes.COPYis a new Canvas-only blend mode that allows you to use thecopycomposite operation when rendering Game Objects.BlendModes.XORis a new Canvas-only blend mode that allows you to use thexorcomposite operation when rendering Game Objects.RenderTexture.eraseis 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 totrueit 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 explicitrenderTypeof either CANVAS or WEBGL. It cannot be left as AUTO. Fix #4166 (thanks @jcyuan) Animation.nextFramewill 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.previousFramewill 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.PointToLinehas a new optional argumentlineThickness(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.GetNearestPointis a new static method that will return the nearest point on a line to the given point.Geom.Line.GetShortestDistanceis a new static method that will return the shortest distance from a line to the given point.Camera.getBoundsis a new method that will return a rectangle containing the bounds of the camera.Camera.centerOnXwill move the camera horizontally to be centered on the given coordinate without changing its vertical placement.Camera.centerOnYwill move the camera vertically to be centered on the given coordinate without changing its horizontally placement.AnimationManager.existsis a new method that will check to see if an Animation using the given key already exists or not and returns a boolean.animationstart-keyis 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 foranimationstart-explode.animationrestart-keyis 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 foranimationrestart-explode.animationcomplete-keyis 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 foranimationcomplete-explode.animationupdate-keyis 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 foranimationupdate-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
startevent when played (either forward, or in reverse) by any Game Object. - The Animation class now emits the
restartevent when it restarts playing on any Game Object. - The Animation class now emits the
completeevent when it finishes playing on any Game Object. - The Animation Component has a new method called
chainwhich 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 itsanimationcompletecallback). 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.drawFrameis a new method that allows you to draw a texture frame to the CanvasTexture based on the texture key and frame given.CanvasTexture.getIndexis a new method that will take an x/y coordinate and return the Image Data index offset used to retrieve the pixel values.CanvasTexture.getPixelsis 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.setPixelis a new method that sets the given pixel in the CanvasTexture to the color and alpha values provided.CanvasTexture.getDatais a new method that will extract an ImageData block from the CanvasTexture from the region given.CanvasTexture.putDatais a new method that will put an ImageData block at the given coordinates in a CanvasTexture.Line.Extendis a new static function that allows you extend the start and/or end points of a Line by the given amounts.Vector2.LEFTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.RIGHTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.UPis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.DOWNis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.ONEis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.ZEROis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.LEFTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.RIGHTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.UPis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.DOWNis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.FORWARDis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.BACKis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.ONEis a new constant that can be used in Vector comparison operations (thanks @Aedalus)- Geometery Mask has a new property called
invertAlphain 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
maxSpeedwhich limits the vector length of the Body velocity. You can set it via the methodsetMaxSpeedand it is applied in theWorld.computeVelocitymethod (thanks @Edwin222 @rexrainbow) WebGLRenderer.snapshotAreais 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 assnapshotexcept you control the area being grabbed, so is more efficient if you only need a smaller area.WebGLRenderer.snapshotPixelis a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as aColorobject to your specified callback.CanvasRenderer.snapshotAreais 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 assnapshotexcept you control the area being grabbed, so is more efficient if you only need a smaller area.CanvasRenderer.snapshotPixelis a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as aColorobject to your specified callback.SceneManager.getScenesis 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.GetTargetis a new helper function that will return a reference to a DOM Element based on the given string or node.GameObjects.Externis 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.defaultStrokeWidthto set the stroke width of any debug drawn body, previously it was always 1 (thanks @samme) TextStyle.setFonthas a new optional argumentupdateTextwhich will sets if the text should be automatically updated or not (thanks @DotTheGreat)ProcessQueue.destroynow sets the internaltoProcesscounter to zero.- The
PathFollower.pathRotationVerticalAdjustproperty 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. TheverticalAdjustargument from thesetRotateToPathmethod has been removed as well. - The config value
preserveDrawingBufferhas been removed as it has never been used by the WebGL Renderer. PluginManager.installreturnsnullif the plugin failed to install in all cases.PluginFilewill now install the plugin into the current Scene as long as thestartormappingarguments 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
callbackDataobject instead, like the WebGL renderer does. WebGLRenderer.setBlendModehas a new optional argumentforce, which will force the given blend mode to be set, regardless of the current settings.- The method
DisplayList.sortGameObjectshas 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.getTopGameObjecthas 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.setFramebufferhas a new optional boolean argumentupdateScissor, which will reset the scissor to match the framebuffer size, or clear it.WebAudioSoundManager.onFocuswill not try to resume the Audio Context if it's still locked.WebAudioSoundManager.onBlurwill 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.strokeis a new alias for thestrokePathmethod, to keep the calls consistent with the Canvas Rendering Context API.Graphics.fillis a new alias for thefillPathmethod, to keep the calls consistent with the Canvas Rendering Context API.LoaderPlugin.sceneManageris a new property that is a reference to the global Scene Manager, useful for Plugins.- Whenever
Camera.roundPixelswas 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 toMath.roundinstead. 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.createwill now return a booleanfalseif the given key is invalid (i.e. undefined or falsey).AnimationManager.createwill 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, theaddevent is emitted by the Animation Manager. If no event is emitted, the animation already existed.ArcadePhysics.Body.destroywill now only add itself to the WorldpendingDestroylist if the world property exists. This preventsCannot read property 'pendingDestroy' of undefinederrors 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
restartmethod has had is solekeyargument 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.playandplayReversewill 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.clearnow has 4 new optional arguments:x, y, width, heightwhich 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.batchQuadandbatchTrihave two new optional argumentstextureandunitwhich are used to re-set the batch texture should the method cause a batch flush.TextureTintPipeline.requireTextureBatchis a new internal method that helps speed-up the creation of texture batches. It is used in conjunction withsetTexture2DandpushBatch.TextureTintPipeline.flushandTextureTintPipeline.pushBatchhave been optimized to handle zero based texture units as priority. They've also been refactored to avoid creation of empty texture batches.- The
WebGLRenderer.setTexture2Dmethod has a new optional argumentflushwhich 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
widthandheightproperties are now based on the tilemap tile sizes multiplied by the layer dimensions. This corrects an issue with layer sizes being wrong if you calledsetBaseTileSizeon a Map. - The WebGLRenderer will now clear the framebuffer at the start of every render.
WebGLRenderer.setScissornow has a new optional argumentdrawingBufferHeightwhich allows you to specify the drawing buffer height, rather than use the renderers default value.WebGLRenderer.pushScissornow has a new optional argumentdrawingBufferHeightwhich allows you to specify the drawing buffer height, rather than use the renderers default value.WebGLRenderer.preRendernow callsgl.clearColorin order to restore the background clear color in case something, like a Render Texture, has changed it.Map.setwill 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.MatterSpritewould set itstypeproperty to beImage. It now sets it to beSpriteas it should do.Matter.TileBody.setFromTileCollisionno 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
transitionstartevent is now dispatched by the Target Scene of a transition, regardless if the Scene has acreatemethod 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.restartnow returns the Tween instance (thanks @rexrainbow)Tween.playnow returns the Tween instance (thanks @rexrainbow)Tween.seeknow returns the Tween instance (thanks @rexrainbow)Tween.completenow returns the Tween instance (thanks @rexrainbow)Tween.stopnow returns the Tween instance (thanks @rexrainbow)List.sortnow has an optional parameterhandlerwhich allows you to provide your own sort handling function (thanks @jcyuan)Container.sortnow has an optional parameterhandlerwhich allows you to provide your own sort handling function (thanks @jcyuan)- The WebGLRenderer method
canvasToTexturewill now only set the filter to beNEARESTifantialiasis 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 callingtexture.setFilter(1)on them. CanvasRenderer.snapshotCallback,snapshotTypeandsnapshotEncoderhave all been removed as they are no longer required.CanvasRenderer.snapshotStateis a new object that contains the snapshot configuration data, the same as the WebGL Renderer.- The signature of the
WebGLSnapshotfunction has changed. It now takes a Snapshot Configuration object as the second parameter. - The signature of the
CanvasSnapshotfunction 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
onCompletecallback or sending theCOMPLETEevent. This means you can now call methods that will change the state of the Timeline, such asplay, during the callback handlers, where-as before doing this would have had the internal state changed immediately, preventing it (thanks Lucas Knight) - The
AddToDOMmethod has had theoverflowHiddenargument removed. The DOM element the canvas is inserted into no longer hasoverflow: hiddenapplied 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,fontSizeandfontStylein eitherText.setStyleorsetFont, 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.toJSONwasn'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 erroras 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.cullmethod 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.ReverseRowswas actually reversing the columns, but now reverses the rows.Array.Matrix.ReverseColumnswas 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
fillRectcalls 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
cameraFilterproperty 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.startFollowmethod now properly uses thestartAtargument 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
HTML5AudioSoundinstance, via themutesetter, now works as it does via the Sound Manager (thanks @Waclaw-I @neon-dev) - Changing the volume on an
HTML5AudioSoundinstance, via thevolumesetter, 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.tilesetnow returns the specific Tileset associated with the tile rather than an array of them. Fix #4095 (thanks @quadrupleslap)Tile.getCollisionGroupwouldn't return the correct Group after the change to support multiple Tilesets. It now returns the group properly (thanks @jbpuryear)Tile.getTileDatawouldn't return the correct data after the change to support multiple Tilesets. It now returns the tile data properly (thanks @jbpuryear)- The
GetTileAtandRemoveTileAtcomponents 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.widthorTileSprite.heightwill now flag the texture as dirty and callupdateDisplayOrigin, allowing you to resize TileSprites dynamically in both Canvas and WebGL. RandomDataGenerator.shufflehas 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.indexSortCallbackhas been removed as it's no longer required.Particle.indexhas 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.resetPositionis a new method that is called when a particle dies preparing it for firing again in the future.- The Canvas
SetTransformmethod 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.MoveUpwouldn't let you move an array element to the top-most index in the array. This also impactedContainer.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
batchQuadandbatchTrimethods 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
scaleXorscaleYon aMatterImageorMatterSpritewould 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.resetin Arcade Physics would ignore thexandyvalues 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, thealphaargument would be ignored in Canvas mode. It's now used when filling the RenderTexture. - Fixed an issue in
WebGLRenderer.setScissorwhere it was possible to try and compare the scissor size to a non-current scissor if called outside of the render loop (i.e. fromRenderTexture.fill) (thanks @hackhat) RenderTexture.fillin WebGL would usegl.clearand 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 thedrawFillRectmethod of the Texture Tint Pipeline, allowing it to work properly regardless of camera zoom or size.Container.getFirstwas using an incorrect Array Utils functionGetFirstElementwhen it should have been usingGetFirst. It now uses the correct function. Fix #4244 (thanks @miran248)List.getFirstwas using an incorrect Array Utils functionGetFirstElementwhen it should have been usingGetFirst. 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.destroyis 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
processDomCallbacksmethod in the Input Manager wasn't correctly clearing theoncearrays. Responsibility for this has now been passed to the queue methodsqueueTouchStart,queueTouchMove,queueTouchEnd,queueMouseDown,queueMouseMoveandqueueMouseUp. Fix #4257 (thanks @iArePJ) - Arcade Physics now manages when
postUpdateshould 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
collideevent on a Body even if it performing an overlap check, if theonCollideproperty 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 = truein the game config (thanks @gomachan7) List.sortwas missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)Container.sortwas missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)DataManager.popwould 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
GetValuefunction 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.Bootnamespace has been renamed toPhaser.Core. As a result, thebootfolder has been renamed tocore. This impacts theTimeStepclass andVisibilityHandlerfunction, which have been moved to be under the new namespace. - The
Phaser.Animationsnamespace was incorrectly exposed in the Phaser entrypoints asAnimation(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 fromPhaser.AnimationtoPhaser.Animations, i.e.Phaser.Animation.AnimationFrametoPhaser.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_tochangedata-to keep it consistent with other keyed events. Note the change from_to-. - The Keyboard Plugin
keydowndynamic event string has changed fromkeydown_tokeydown-to keep it consistent with other keyed events. Note the change from_to-. - The Keyboard Plugin
keyupdynamic event string has changed fromkeyup_tokeyup-to keep it consistent with other keyed events. Note the change from_to-. - The
texturesreadyevent emitted by the Texture Manager has been renamed toready. - The
loadcompleteevent emitted by the Loader Plugin has been renamed topostprocessto be reflect what it's used for. - Game Objects used to emit a
collideevent if they had an Arcade Physics Body withonCollideset, that collided with a Tile. This has changed. The event has been renamed totilecollideand 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
overlapevent if they had an Arcade Physics Body withonOverlapset, that overlapped with a Tile. This has changed. The event has been renamed totileoverlapand 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.SeperateXhas been renamed toSeparateXto correct the spelling mistake. - The function
Phaser.Physics.Impact.SeperateYhas been renamed toSeparateYto correct the spelling mistake. - The
endedevent inWebAudioSoundhas been renamed tocompleteto make it more consistent with the rest of the API. - The
endedevent inHTML5AudioSoundhas been renamed tocompleteto make it more consistent with the rest of the API. - The
Phaser.Utils.Objectsnamespace was incorrectly exposed in the Phaser entrypoints asObject(note the lack of plural), this has now been fixed so all associated functions are properly namespaced. Phaser.GameObjects.Blitter.Bobhas been renamed toPhaser.GameObjects.Bobto avoid namespace conflicts in TypeScript.Phaser.GameObjects.Text.TextStylehas been renamed toPhaser.GameObjects.TextStyleto 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.addUpCallbackmethod.InputPlugin.addDownCallbackmethod.InputPlugin.addMoveCallbackmethod.InputManager.queueproperty.InputManager.domCallbacksproperty.InputManager._hasUpCallbackproperty.InputManager._hasDownCallbackproperty.InputManager._hasMoveCallbackproperty.InputManager.processDomCallbacksmethod.InputManager.addUpCallbackmethod.InputManager.addDownCallbackmethod.InputManager.addMoveCallbackmethod.
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_KEYevent name has changed tokeydown-KEY. Note the change from an underscore to a hyphen. - In all cases the
keyup_KEYevent name has changed tokeyup-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.addCaptureis a new method that allows you to define a set of keycodes to have the default browser behaviors disabled on.KeyboardPlugin.removeCaptureis a new method that removes specific previously set key captures.KeyboardPlugin.clearCapturesis a new method that removes all key captures.KeyboardPlugin.getCapturesis a new method that returns an array of all current key captures.KeyboardPlugin.enableGlobalCaptureis a new method that enables any key captures that have been created.KeyboardPlugin.disableGlobalCaptureis a new method that disables any key captures that have been created, without removing them from the captures list.KeyboardPlugin.addKeyhas a new boolean argumentenableCapture, which is true by default, that will add a key capture for the Key being created.KeyboardPlugin.addKeyshas a new boolean argumentenableCapture, 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, theKeyboardPlugindid 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. theKeyboardPluginclass still exists, and is still the main point of interface when you callthis.input.keyboardin 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.capturewhich 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
preventDefaultonly 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.emitOnRepeatis a new boolean property that controls if the Key will continuously emit adownevent while being held down (true), or emit the event just once, on first press, and then skip future events (false).Key.setEmitOnRepeatis a new chainable method for setting theemitOnRepeatproperty.- The
KeyboardPlugin.addKeysmethod has a new optional booleanemitOnRepeatwhich sets that property on all Key objects it creates as part of the call. It defaults tofalse. - The
KeyboardPlugin.addKeymethod has a new optional booleanemitOnRepeatwhich sets that property on the Key object it creates. It defaults tofalse. - The
Keyclass now extends EventEmitter and emits two events directly:downandup. 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_FIREFOXandBRACKET_LEFT_FIREFOX(thanks @wmateam) Key.onDownis a new method that handles the Key being pressed down, including down repeats.Key.onUpis a new method that handles the Key being released.Key.destroyis a new method that handles Key instance destruction. It is called automatically inKeyboardPlugin.destroy.- The
Key.preventDefaultproperty has been removed. This is now handled by the global keyboard capture methods. Key.metaKeyis 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.keyboardis a new property that instantiates the global Keyboard Manager, if enabled in the game config.- The
KeyboardPlugin.addKeymethod has a new boolean propertyenableCapturewhich automatically prevents default on the Key being created. - The
KeyboardPlugin.addKeysmethod has a new boolean propertyenableCapturewhich automatically prevents default on Keys being created. Phaser.Input.Keyboard.ProcessKeyDownhas been removed as it's no longer required,Key.onDownhandles it instead.Phaser.Input.Keyboard.ProcessKeyUphas been removed as it's no longer required,Key.onUphandles it instead.- The Keyboard Manager has a property called
captureswhich is an array of keycodes, as populated by the Game Config. Any key code in the array will havepreventDefaultcalled on it if pressed. KeyboardPlugin.manageris a new property that references the Keyboard Manager and is used internally.KeyboardPlugin.targethas been removed as it's no longer used by the class.KeyboardPlugin.queuehas been removed as it's no longer used by the class.KeyboardPlugin.onKeyHandlerhas been removed as it's no longer used by the class.KeyboardPlugin.startListenershas been removed as it's no longer used by the class.KeyboardPlugin.stopListenershas 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
startListenersmethod. - When enabling a Game Object for input it will now use the
widthandheightproperties 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.smoothFactoris 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.inputSmoothFactoris 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 asinput: { smoothFactor: value }.InputManager.transformPointerhas a new boolean argumentwasMove, which controls if the pointer is being transformed after a move or up/down event.Pointer.velocityis 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 thePointer.motionFactorproperty. 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.angleis 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 thePointer.motionFactorproperty. 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.distanceis 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 thePointer.motionFactorproperty. 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.motionFactoris 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
preUpdateevent, with the capital U, instead ofpreupdate. This has now been corrected. Fix #4185 (thanks @gadelan) Pointer.updateMotionis 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.timeis a new property that holds the time the Pointer was last updated by the Game step.Pointer.getDistancehas 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.getDistanceXis 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.getDistanceYis 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.getDurationis 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.getAngleis 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'sdownXanddownYvalues 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
mousedownlistener for the game canvas and then callwindow.focuswhen detected (assuming the game configautoFocusproperty wastrue). Responsibility for this has now been moved to the Mouse ManageronMouseDownhandler. - In previous versions, the VisibilityHandler would create a
mouseoutlistener for the game canvas and then setgame.isOverwhen detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input ManagerisOverproperty directly. - In previous versions, the VisibilityHandler would create a
mouseoverlistener for the game canvas and then setgame.isOverwhen detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input ManagerisOverproperty directly. - The
Phaser.Game.isOverproperty 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 dothis.input.isOverfrom 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 withthis.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 withthis.input.on('gameout')from within a Scene. - The Game used to emit a
mouseoverevent 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 eventgameover. - The Game used to emit a
mouseoutevent 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 eventgameout. - If the
windowobject exists (which it will in normal browser environments) newmouseupandtouchendevent listeners are bound to it and trigger the normalmouseuportouchendevents within the internal input system. This means you will now get apointerupevent 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
autoFocusgame 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 withthis.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 withthis.input.on('pointerupoutside')from within a Scene. Pointer.downElementis 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.upElementis 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.dragStateproperty has been removed. This is no longer used internally as it has to be tracked per Scene, not on a global level. InputPlugin.setDragStateis a new internal method that sets the drag state for the given Pointer.InputPlugin.getDragStateis 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.leftButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.rightButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.middleButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.backButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.forwardButtonDownwill 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.moveandPointer.downnow useinto check for the existance of thebuttonsproperty 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
zoomto be > 1 then it will automatically enablepixelArtmode, unless you setpixelArt: falsein 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 isfalse(turned off). - The Game Config property
autoResizehas been removed as it's now redundant. - The WebGL and Canvas Renderers no longer change the Canvas size in their
resizemethods. They just update internal properties. - The WebGL and Canvas Renderers now read the
width,heightandresolutionvalues from the Scale Manager, not the Game Config. CameraManager.baseScaleproperty has been removed as it's no longer used anywhere.- The BaseCamera and Camera
preRendermethods now only take a resolution argument and use it internally for their transforms. InputManager.scaleManageris a new property that is a reference to the Scale Manager. This is populated in thebootmethod.- The
InputManager.transformXmethod has been removed. This is now available in the ScaleManager. - The
InputManager.transformYmethod has been removed. This is now available in the ScaleManager. - The
InputManager.scaleproperty has been removed. This is now available in the ScaleManager underdisplayScale. - The
InputManager.resizemethod has been removed as this process is now handled by the ScaleManager. - The
InputManager.boundsproperty has been removed as this process is now handled by the ScaleManager. - The
InputManager.updateBoundsmethod has been removed as this process is now handled by the ScaleManager. - The
InputManager.getOffsetXmethod has been removed as it's no longer required. - The
InputManager.getOffsetYmethod has been removed as it's no longer required. - The
InputManager.getScaleXmethod has been removed as it's no longer required. - The
InputManager.getScaleYmethod has been removed as it's no longer required. - The
SceneManager.resizemethod has been removed as it's no longer required. - The
Scene.Systems.resizemethod has been removed as it's no longer required. - Scenes will no longer dispatch the
resizeevent. You should now listen for this event from the Scale Manager instead. BaseCamera.confighas been removed as it's no longer required.BaseCamera.scaleManageris a new property that references the Scale Manager and is used internally for size checks.- The
Game.resizemethod has been removed as it's no longer required. You should now callScaleManager.resizeinstead. - The Game will no longer dispatch the
resizeevent. You should now listen for this event from the Scale Manager instead.
Facebook Instant Games Updates and Fixes
- Added the
Leaderboard.getConnectedScoresmethod, to get a list of scores from player connected entries. - The
loadPlayerPhotofunction in the Instant Games plugin now listens for the updated Loader event correctly, causing thephotocompleteevent to fire properly. Leaderboard.setScorenow emits the LeaderboardScore object with thesetscoreevent, as the documentation said it did.Leaderboard.getPlayerScorenow only populates theplayerScoreproperty if the entry isn'tnull.- If the
setScoreorgetPlayerScorecalls fail, it will returnnullas the score instance, instead of causing a run-time error. - You can now pass an object or a string to
setScoreand objects will be automatically stringified. - The
preloadAdsmethod will now only create an AdInstance object if the interstitialloadSyncpromise resolves. - The
preloadVideoAdsmethod will now only create an AdInstance object if the interstitialloadSyncpromise resolves. - The
preloadAdsmethod will now emit theadsnofillevent, if there are no ads in the inventory to load. - The
preloadVideoAdsmethod will now emit theadsnofillevent, if there are no ads in the inventory to load. - The
showAdmethod will now emit theadsnotloadedevent, if there are no ads loaded matching the given Placement ID. - The
showVideomethod will now emit theadsnotloadedevent, if there are no ads loaded matching the given Placement ID. - Showing an ad will emit the
adfinishedevent when the ad is closed, previously this event was calledshowadbut the new name better reflects what has happened. - The Facebook Plugin is now available in the
Phaser.Sceneclass template under thefacebookproperty (thanks @bryanwood) - Fixed the
Leaderboard.getScoresmethod to now take the arguments into account. Fix #4271 (thanks @Oramy) - Fixed an API validation error in the
chooseContextmethod. Fix #4248 (thanks @yadurajiv)
New Features
- You can now load external Scene files using the new
load.sceneFilemethod. 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
setStatewhich will set the state property in a chainable call. BlendModes.ERASEis 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_INis a new Canvas-only blend mode that allows you to use thesource-incomposite operation when rendering Game Objects.BlendModes.SOURCE_OUTis a new Canvas-only blend mode that allows you to use thesource-outcomposite operation when rendering Game Objects.BlendModes.SOURCE_ATOPis a new Canvas-only blend mode that allows you to use thesource-atopcomposite operation when rendering Game Objects.BlendModes.DESTINATION_OVERis a new Canvas-only blend mode that allows you to use thedestination-overcomposite operation when rendering Game Objects.BlendModes.DESTINATION_INis a new Canvas-only blend mode that allows you to use thedestination-incomposite operation when rendering Game Objects.BlendModes.DESTINATION_OUTis a new Canvas-only blend mode that allows you to use thedestination-outcomposite operation when rendering Game Objects.BlendModes.DESTINATION_ATOPis a new Canvas-only blend mode that allows you to use thedestination-atopcomposite operation when rendering Game Objects.BlendModes.LIGHTERis a new Canvas-only blend mode that allows you to use thelightercomposite operation when rendering Game Objects.BlendModes.COPYis a new Canvas-only blend mode that allows you to use thecopycomposite operation when rendering Game Objects.BlendModes.XORis a new Canvas-only blend mode that allows you to use thexorcomposite operation when rendering Game Objects.RenderTexture.eraseis 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 totrueit 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 explicitrenderTypeof either CANVAS or WEBGL. It cannot be left as AUTO. Fix #4166 (thanks @jcyuan) Animation.nextFramewill 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.previousFramewill 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.PointToLinehas a new optional argumentlineThickness(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.GetNearestPointis a new static method that will return the nearest point on a line to the given point.Geom.Line.GetShortestDistanceis a new static method that will return the shortest distance from a line to the given point.Camera.getBoundsis a new method that will return a rectangle containing the bounds of the camera.Camera.centerOnXwill move the camera horizontally to be centered on the given coordinate without changing its vertical placement.Camera.centerOnYwill move the camera vertically to be centered on the given coordinate without changing its horizontally placement.AnimationManager.existsis a new method that will check to see if an Animation using the given key already exists or not and returns a boolean.animationstart-keyis 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 foranimationstart-explode.animationrestart-keyis 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 foranimationrestart-explode.animationcomplete-keyis 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 foranimationcomplete-explode.animationupdate-keyis 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 foranimationupdate-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
startevent when played (either forward, or in reverse) by any Game Object. - The Animation class now emits the
restartevent when it restarts playing on any Game Object. - The Animation class now emits the
completeevent when it finishes playing on any Game Object. - The Animation Component has a new method called
chainwhich 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 itsanimationcompletecallback). 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.drawFrameis a new method that allows you to draw a texture frame to the CanvasTexture based on the texture key and frame given.CanvasTexture.getIndexis a new method that will take an x/y coordinate and return the Image Data index offset used to retrieve the pixel values.CanvasTexture.getPixelsis 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.setPixelis a new method that sets the given pixel in the CanvasTexture to the color and alpha values provided.CanvasTexture.getDatais a new method that will extract an ImageData block from the CanvasTexture from the region given.CanvasTexture.putDatais a new method that will put an ImageData block at the given coordinates in a CanvasTexture.Line.Extendis a new static function that allows you extend the start and/or end points of a Line by the given amounts.Vector2.LEFTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.RIGHTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.UPis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.DOWNis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.ONEis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.ZEROis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.LEFTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.RIGHTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.UPis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.DOWNis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.FORWARDis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.BACKis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.ONEis a new constant that can be used in Vector comparison operations (thanks @Aedalus)- Geometery Mask has a new property called
invertAlphain 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
maxSpeedwhich limits the vector length of the Body velocity. You can set it via the methodsetMaxSpeedand it is applied in theWorld.computeVelocitymethod (thanks @Edwin222 @rexrainbow) WebGLRenderer.snapshotAreais 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 assnapshotexcept you control the area being grabbed, so is more efficient if you only need a smaller area.WebGLRenderer.snapshotPixelis a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as aColorobject to your specified callback.CanvasRenderer.snapshotAreais 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 assnapshotexcept you control the area being grabbed, so is more efficient if you only need a smaller area.CanvasRenderer.snapshotPixelis a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as aColorobject to your specified callback.SceneManager.getScenesis 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.GetTargetis a new helper function that will return a reference to a DOM Element based on the given string or node.GameObjects.Externis 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.defaultStrokeWidthto set the stroke width of any debug drawn body, previously it was always 1 (thanks @samme) TextStyle.setFonthas a new optional argumentupdateTextwhich will sets if the text should be automatically updated or not (thanks @DotTheGreat)ProcessQueue.destroynow sets the internaltoProcesscounter to zero.- The
PathFollower.pathRotationVerticalAdjustproperty 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. TheverticalAdjustargument from thesetRotateToPathmethod has been removed as well. - The config value
preserveDrawingBufferhas been removed as it has never been used by the WebGL Renderer. PluginManager.installreturnsnullif the plugin failed to install in all cases.PluginFilewill now install the plugin into the current Scene as long as thestartormappingarguments 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
callbackDataobject instead, like the WebGL renderer does. WebGLRenderer.setBlendModehas a new optional argumentforce, which will force the given blend mode to be set, regardless of the current settings.- The method
DisplayList.sortGameObjectshas 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.getTopGameObjecthas 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.setFramebufferhas a new optional boolean argumentupdateScissor, which will reset the scissor to match the framebuffer size, or clear it.WebAudioSoundManager.onFocuswill not try to resume the Audio Context if it's still locked.WebAudioSoundManager.onBlurwill 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.strokeis a new alias for thestrokePathmethod, to keep the calls consistent with the Canvas Rendering Context API.Graphics.fillis a new alias for thefillPathmethod, to keep the calls consistent with the Canvas Rendering Context API.LoaderPlugin.sceneManageris a new property that is a reference to the global Scene Manager, useful for Plugins.- Whenever
Camera.roundPixelswas 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 toMath.roundinstead. 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.createwill now return a booleanfalseif the given key is invalid (i.e. undefined or falsey).AnimationManager.createwill 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, theaddevent is emitted by the Animation Manager. If no event is emitted, the animation already existed.ArcadePhysics.Body.destroywill now only add itself to the WorldpendingDestroylist if the world property exists. This preventsCannot read property 'pendingDestroy' of undefinederrors 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
restartmethod has had is solekeyargument 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.playandplayReversewill 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.clearnow has 4 new optional arguments:x, y, width, heightwhich 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.batchQuadandbatchTrihave two new optional argumentstextureandunitwhich are used to re-set the batch texture should the method cause a batch flush.TextureTintPipeline.requireTextureBatchis a new internal method that helps speed-up the creation of texture batches. It is used in conjunction withsetTexture2DandpushBatch.TextureTintPipeline.flushandTextureTintPipeline.pushBatchhave been optimized to handle zero based texture units as priority. They've also been refactored to avoid creation of empty texture batches.- The
WebGLRenderer.setTexture2Dmethod has a new optional argumentflushwhich 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
widthandheightproperties are now based on the tilemap tile sizes multiplied by the layer dimensions. This corrects an issue with layer sizes being wrong if you calledsetBaseTileSizeon a Map. - The WebGLRenderer will now clear the framebuffer at the start of every render.
WebGLRenderer.setScissornow has a new optional argumentdrawingBufferHeightwhich allows you to specify the drawing buffer height, rather than use the renderers default value.WebGLRenderer.pushScissornow has a new optional argumentdrawingBufferHeightwhich allows you to specify the drawing buffer height, rather than use the renderers default value.WebGLRenderer.preRendernow callsgl.clearColorin order to restore the background clear color in case something, like a Render Texture, has changed it.Map.setwill 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.MatterSpritewould set itstypeproperty to beImage. It now sets it to beSpriteas it should do.Matter.TileBody.setFromTileCollisionno 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
transitionstartevent is now dispatched by the Target Scene of a transition, regardless if the Scene has acreatemethod 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.restartnow returns the Tween instance (thanks @rexrainbow)Tween.playnow returns the Tween instance (thanks @rexrainbow)Tween.seeknow returns the Tween instance (thanks @rexrainbow)Tween.completenow returns the Tween instance (thanks @rexrainbow)Tween.stopnow returns the Tween instance (thanks @rexrainbow)List.sortnow has an optional parameterhandlerwhich allows you to provide your own sort handling function (thanks @jcyuan)Container.sortnow has an optional parameterhandlerwhich allows you to provide your own sort handling function (thanks @jcyuan)- The WebGLRenderer method
canvasToTexturewill now only set the filter to beNEARESTifantialiasis 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 callingtexture.setFilter(1)on them. CanvasRenderer.snapshotCallback,snapshotTypeandsnapshotEncoderhave all been removed as they are no longer required.CanvasRenderer.snapshotStateis a new object that contains the snapshot configuration data, the same as the WebGL Renderer.- The signature of the
WebGLSnapshotfunction has changed. It now takes a Snapshot Configuration object as the second parameter. - The signature of the
CanvasSnapshotfunction 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
onCompletecallback or sending theCOMPLETEevent. This means you can now call methods that will change the state of the Timeline, such asplay, during the callback handlers, where-as before doing this would have had the internal state changed immediately, preventing it (thanks Lucas Knight) - The
AddToDOMmethod has had theoverflowHiddenargument removed. The DOM element the canvas is inserted into no longer hasoverflow: hiddenapplied 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,fontSizeandfontStylein eitherText.setStyleorsetFont, 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.toJSONwasn'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 erroras 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.cullmethod 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.ReverseRowswas actually reversing the columns, but now reverses the rows.Array.Matrix.ReverseColumnswas 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
fillRectcalls 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
cameraFilterproperty 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.startFollowmethod now properly uses thestartAtargument 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
HTML5AudioSoundinstance, via themutesetter, now works as it does via the Sound Manager (thanks @Waclaw-I @neon-dev) - Changing the volume on an
HTML5AudioSoundinstance, via thevolumesetter, 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.tilesetnow returns the specific Tileset associated with the tile rather than an array of them. Fix #4095 (thanks @quadrupleslap)Tile.getCollisionGroupwouldn't return the correct Group after the change to support multiple Tilesets. It now returns the group properly (thanks @jbpuryear)Tile.getTileDatawouldn't return the correct data after the change to support multiple Tilesets. It now returns the tile data properly (thanks @jbpuryear)- The
GetTileAtandRemoveTileAtcomponents 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.widthorTileSprite.heightwill now flag the texture as dirty and callupdateDisplayOrigin, allowing you to resize TileSprites dynamically in both Canvas and WebGL. RandomDataGenerator.shufflehas 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.indexSortCallbackhas been removed as it's no longer required.Particle.indexhas 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.resetPositionis a new method that is called when a particle dies preparing it for firing again in the future.- The Canvas
SetTransformmethod 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.MoveUpwouldn't let you move an array element to the top-most index in the array. This also impactedContainer.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
batchQuadandbatchTrimethods 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
scaleXorscaleYon aMatterImageorMatterSpritewould 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.resetin Arcade Physics would ignore thexandyvalues 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, thealphaargument would be ignored in Canvas mode. It's now used when filling the RenderTexture. - Fixed an issue in
WebGLRenderer.setScissorwhere it was possible to try and compare the scissor size to a non-current scissor if called outside of the render loop (i.e. fromRenderTexture.fill) (thanks @hackhat) RenderTexture.fillin WebGL would usegl.clearand 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 thedrawFillRectmethod of the Texture Tint Pipeline, allowing it to work properly regardless of camera zoom or size.Container.getFirstwas using an incorrect Array Utils functionGetFirstElementwhen it should have been usingGetFirst. It now uses the correct function. Fix #4244 (thanks @miran248)List.getFirstwas using an incorrect Array Utils functionGetFirstElementwhen it should have been usingGetFirst. 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.destroyis 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
processDomCallbacksmethod in the Input Manager wasn't correctly clearing theoncearrays. Responsibility for this has now been passed to the queue methodsqueueTouchStart,queueTouchMove,queueTouchEnd,queueMouseDown,queueMouseMoveandqueueMouseUp. Fix #4257 (thanks @iArePJ) - Arcade Physics now manages when
postUpdateshould 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
collideevent on a Body even if it performing an overlap check, if theonCollideproperty 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 = truein the game config (thanks @gomachan7) List.sortwas missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)Container.sortwas missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)DataManager.popwould 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
GetValuefunction 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.getConnectedScoresmethod, to get a list of scores from player connected entries. - The
loadPlayerPhotofunction in the Instant Games plugin now listens for the updated Loader event correctly, causing thephotocompleteevent to fire properly. Leaderboard.setScorenow emits the LeaderboardScore object with thesetscoreevent, as the documentation said it did.Leaderboard.getPlayerScorenow only populates theplayerScoreproperty if the entry isn'tnull.- If the
setScoreorgetPlayerScorecalls fail, it will returnnullas the score instance, instead of causing a run-time error. - You can now pass an object or a string to
setScoreand objects will be automatically stringified. - The
preloadAdsmethod will now only create an AdInstance object if the interstitialloadSyncpromise resolves. - The
preloadVideoAdsmethod will now only create an AdInstance object if the interstitialloadSyncpromise resolves. - The
preloadAdsmethod will now emit theadsnofillevent, if there are no ads in the inventory to load. - The
preloadVideoAdsmethod will now emit theadsnofillevent, if there are no ads in the inventory to load. - The
showAdmethod will now emit theadsnotloadedevent, if there are no ads loaded matching the given Placement ID. - The
showVideomethod will now emit theadsnotloadedevent, if there are no ads loaded matching the given Placement ID. - Showing an ad will emit the
adfinishedevent when the ad is closed, previously this event was calledshowadbut the new name better reflects what has happened. - The Facebook Plugin is now available in the
Phaser.Sceneclass template under thefacebookproperty (thanks @bryanwood) - Fixed the
Leaderboard.getScoresmethod to now take the arguments into account. Fix #4271 (thanks @Oramy) - Fixed an API validation error in the
chooseContextmethod. 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.addUpCallbackmethod.InputPlugin.addDownCallbackmethod.InputPlugin.addMoveCallbackmethod.InputManager.queueproperty.InputManager.domCallbacksproperty.InputManager._hasUpCallbackproperty.InputManager._hasDownCallbackproperty.InputManager._hasMoveCallbackproperty.InputManager.processDomCallbacksmethod.InputManager.addUpCallbackmethod.InputManager.addDownCallbackmethod.InputManager.addMoveCallbackmethod.
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_KEYevent name has changed tokeydown-KEY. Note the change from an underscore to a hyphen. - In all cases the
keyup_KEYevent name has changed tokeyup-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.addCaptureis a new method that allows you to define a set of keycodes to have the default browser behaviors disabled on.KeyboardPlugin.removeCaptureis a new method that removes specific previously set key captures.KeyboardPlugin.clearCapturesis a new method that removes all key captures.KeyboardPlugin.getCapturesis a new method that returns an array of all current key captures.KeyboardPlugin.enableGlobalCaptureis a new method that enables any key captures that have been created.KeyboardPlugin.disableGlobalCaptureis a new method that disables any key captures that have been created, without removing them from the captures list.KeyboardPlugin.addKeyhas a new boolean argumentenableCapture, which is true by default, that will add a key capture for the Key being created.KeyboardPlugin.addKeyshas a new boolean argumentenableCapture, 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, theKeyboardPlugindid 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. theKeyboardPluginclass still exists, and is still the main point of interface when you callthis.input.keyboardin 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.capturewhich 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
preventDefaultonly 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.emitOnRepeatis a new boolean property that controls if the Key will continuously emit adownevent while being held down (true), or emit the event just once, on first press, and then skip future events (false).Key.setEmitOnRepeatis a new chainable method for setting theemitOnRepeatproperty.- The
KeyboardPlugin.addKeysmethod has a new optional booleanemitOnRepeatwhich sets that property on all Key objects it creates as part of the call. It defaults tofalse. - The
KeyboardPlugin.addKeymethod has a new optional booleanemitOnRepeatwhich sets that property on the Key object it creates. It defaults tofalse. - The
Keyclass now extends EventEmitter and emits two events directly:downandup. 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_FIREFOXandBRACKET_LEFT_FIREFOX(thanks @wmateam) Key.onDownis a new method that handles the Key being pressed down, including down repeats.Key.onUpis a new method that handles the Key being released.Key.destroyis a new method that handles Key instance destruction. It is called automatically inKeyboardPlugin.destroy.- The
Key.preventDefaultproperty has been removed. This is now handled by the global keyboard capture methods. Key.metaKeyis 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.keyboardis a new property that instantiates the global Keyboard Manager, if enabled in the game config.- The
KeyboardPlugin.addKeymethod has a new boolean propertyenableCapturewhich automatically prevents default on the Key being created. - The
KeyboardPlugin.addKeysmethod has a new boolean propertyenableCapturewhich automatically prevents default on Keys being created. Phaser.Input.Keyboard.ProcessKeyDownhas been removed as it's no longer required,Key.onDownhandles it instead.Phaser.Input.Keyboard.ProcessKeyUphas been removed as it's no longer required,Key.onUphandles it instead.- The Keyboard Manager has a property called
captureswhich is an array of keycodes, as populated by the Game Config. Any key code in the array will havepreventDefaultcalled on it if pressed. KeyboardPlugin.manageris a new property that references the Keyboard Manager and is used internally.KeyboardPlugin.targethas been removed as it's no longer used by the class.KeyboardPlugin.queuehas been removed as it's no longer used by the class.KeyboardPlugin.onKeyHandlerhas been removed as it's no longer used by the class.KeyboardPlugin.startListenershas been removed as it's no longer used by the class.KeyboardPlugin.stopListenershas 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
startListenersmethod. - When enabling a Game Object for input it will now use the
widthandheightproperties 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.smoothFactoris 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.inputSmoothFactoris 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 asinput: { smoothFactor: value }.InputManager.transformPointerhas a new boolean argumentwasMove, which controls if the pointer is being transformed after a move or up/down event.Pointer.velocityis 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 thePointer.motionFactorproperty. 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.angleis 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 thePointer.motionFactorproperty. 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.distanceis 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 thePointer.motionFactorproperty. 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.motionFactoris 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
preUpdateevent, with the capital U, instead ofpreupdate. This has now been corrected. Fix #4185 (thanks @gadelan) Pointer.updateMotionis 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.timeis a new property that holds the time the Pointer was last updated by the Game step.Pointer.getDistancehas 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.getDistanceXis 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.getDistanceYis 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.getDurationis 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.getAngleis 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'sdownXanddownYvalues 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
mousedownlistener for the game canvas and then callwindow.focuswhen detected (assuming the game configautoFocusproperty wastrue). Responsibility for this has now been moved to the Mouse ManageronMouseDownhandler. - In previous versions, the VisibilityHandler would create a
mouseoutlistener for the game canvas and then setgame.isOverwhen detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input ManagerisOverproperty directly. - In previous versions, the VisibilityHandler would create a
mouseoverlistener for the game canvas and then setgame.isOverwhen detected. Responsibility for this has now been moved to the Mouse Manager, which sets the new Input ManagerisOverproperty directly. - The
Phaser.Game.isOverproperty 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 dothis.input.isOverfrom 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 withthis.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 withthis.input.on('gameout')from within a Scene. - The Game used to emit a
mouseoverevent 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 eventgameover. - The Game used to emit a
mouseoutevent 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 eventgameout. - If the
windowobject exists (which it will in normal browser environments) newmouseupandtouchendevent listeners are bound to it and trigger the normalmouseuportouchendevents within the internal input system. This means you will now get apointerupevent 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
autoFocusgame 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 withthis.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 withthis.input.on('pointerupoutside')from within a Scene. Pointer.downElementis 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.upElementis 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.dragStateproperty has been removed. This is no longer used internally as it has to be tracked per Scene, not on a global level. InputPlugin.setDragStateis a new internal method that sets the drag state for the given Pointer.InputPlugin.getDragStateis 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.leftButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.rightButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.middleButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.backButtonDownwill now return an actual boolean, rather than the result of the bitwise op (which still evaluated as a boolean, but this is cleaner).Pointer.forwardButtonDownwill 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.moveandPointer.downnow useinto check for the existance of thebuttonsproperty 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
zoomto be > 1 then it will automatically enablepixelArtmode, unless you setpixelArt: falsein 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 isfalse(turned off). - The Game Config property
autoResizehas been removed as it's now redundant. - The WebGL and Canvas Renderers no longer change the Canvas size in their
resizemethods. They just update internal properties. - The WebGL and Canvas Renderers now read the
width,heightandresolutionvalues from the Scale Manager, not the Game Config. CameraManager.baseScaleproperty has been removed as it's no longer used anywhere.- The BaseCamera and Camera
preRendermethods now only take a resolution argument and use it internally for their transforms. InputManager.scaleManageris a new property that is a reference to the Scale Manager. This is populated in thebootmethod.- The
InputManager.transformXmethod has been removed. This is now available in the ScaleManager. - The
InputManager.transformYmethod has been removed. This is now available in the ScaleManager. - The
InputManager.scaleproperty has been removed. This is now available in the ScaleManager underdisplayScale. - The
InputManager.resizemethod has been removed as this process is now handled by the ScaleManager. - The
InputManager.boundsproperty has been removed as this process is now handled by the ScaleManager. - The
InputManager.updateBoundsmethod has been removed as this process is now handled by the ScaleManager. - The
InputManager.getOffsetXmethod has been removed as it's no longer required. - The
InputManager.getOffsetYmethod has been removed as it's no longer required. - The
InputManager.getScaleXmethod has been removed as it's no longer required. - The
InputManager.getScaleYmethod has been removed as it's no longer required. - The
SceneManager.resizemethod has been removed as it's no longer required. - The
Scene.Systems.resizemethod has been removed as it's no longer required. - Scenes will no longer dispatch the
resizeevent. You should now listen for this event from the Scale Manager instead. BaseCamera.confighas been removed as it's no longer required.BaseCamera.scaleManageris a new property that references the Scale Manager and is used internally for size checks.- The
Game.resizemethod has been removed as it's no longer required. You should now callScaleManager.resizeinstead. - The Game will no longer dispatch the
resizeevent. You should now listen for this event from the Scale Manager instead.
Important Namespace Changes
- The
Phaser.Bootnamespace has been renamed toPhaser.Core. As a result, thebootfolder has been renamed tocore. This impacts theTimeStepclass andVisibilityHandlerfunction, which have been moved to be under the new namespace. - The
Phaser.Animationsnamespace was incorrectly exposed in the Phaser entrypoints asAnimation(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 fromPhaser.AnimationtoPhaser.Animations, i.e.Phaser.Animation.AnimationFrametoPhaser.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_tochangedata-to keep it consistent with other keyed events. Note the change from_to-. - The Keyboard Plugin
keydowndynamic event string has changed fromkeydown_tokeydown-to keep it consistent with other keyed events. Note the change from_to-. - The Keyboard Plugin
keyupdynamic event string has changed fromkeyup_tokeyup-to keep it consistent with other keyed events. Note the change from_to-. - The
texturesreadyevent emitted by the Texture Manager has been renamed toready. - The
loadcompleteevent emitted by the Loader Plugin has been renamed topostprocessto be reflect what it's used for. - Game Objects used to emit a
collideevent if they had an Arcade Physics Body withonCollideset, that collided with a Tile. This has changed. The event has been renamed totilecollideand 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
overlapevent if they had an Arcade Physics Body withonOverlapset, that overlapped with a Tile. This has changed. The event has been renamed totileoverlapand 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.SeperateXhas been renamed toSeparateXto correct the spelling mistake. - The function
Phaser.Physics.Impact.SeperateYhas been renamed toSeparateYto correct the spelling mistake. - The
endedevent inWebAudioSoundhas been renamed tocompleteto make it more consistent with the rest of the API. - The
endedevent inHTML5AudioSoundhas been renamed tocompleteto make it more consistent with the rest of the API.
New Features
- You can now load external Scene files using the new
load.sceneFilemethod. 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
setStatewhich will set the state property in a chainable call. BlendModes.ERASEis 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_INis a new Canvas-only blend mode that allows you to use thesource-incomposite operation when rendering Game Objects.BlendModes.SOURCE_OUTis a new Canvas-only blend mode that allows you to use thesource-outcomposite operation when rendering Game Objects.BlendModes.SOURCE_ATOPis a new Canvas-only blend mode that allows you to use thesource-atopcomposite operation when rendering Game Objects.BlendModes.DESTINATION_OVERis a new Canvas-only blend mode that allows you to use thedestination-overcomposite operation when rendering Game Objects.BlendModes.DESTINATION_INis a new Canvas-only blend mode that allows you to use thedestination-incomposite operation when rendering Game Objects.BlendModes.DESTINATION_OUTis a new Canvas-only blend mode that allows you to use thedestination-outcomposite operation when rendering Game Objects.BlendModes.DESTINATION_ATOPis a new Canvas-only blend mode that allows you to use thedestination-atopcomposite operation when rendering Game Objects.BlendModes.LIGHTERis a new Canvas-only blend mode that allows you to use thelightercomposite operation when rendering Game Objects.BlendModes.COPYis a new Canvas-only blend mode that allows you to use thecopycomposite operation when rendering Game Objects.BlendModes.XORis a new Canvas-only blend mode that allows you to use thexorcomposite operation when rendering Game Objects.RenderTexture.eraseis 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 totrueit 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 explicitrenderTypeof either CANVAS or WEBGL. It cannot be left as AUTO. Fix #4166 (thanks @jcyuan) Animation.nextFramewill 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.previousFramewill 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.PointToLinehas a new optional argumentlineThickness(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.GetNearestPointis a new static method that will return the nearest point on a line to the given point.Geom.Line.GetShortestDistanceis a new static method that will return the shortest distance from a line to the given point.Camera.getBoundsis a new method that will return a rectangle containing the bounds of the camera.Camera.centerOnXwill move the camera horizontally to be centered on the given coordinate without changing its vertical placement.Camera.centerOnYwill move the camera vertically to be centered on the given coordinate without changing its horizontally placement.AnimationManager.existsis a new method that will check to see if an Animation using the given key already exists or not and returns a boolean.animationstart-keyis 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 foranimationstart-explode.animationrestart-keyis 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 foranimationrestart-explode.animationcomplete-keyis 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 foranimationcomplete-explode.animationupdate-keyis 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 foranimationupdate-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
startevent when played (either forward, or in reverse) by any Game Object. - The Animation class now emits the
restartevent when it restarts playing on any Game Object. - The Animation class now emits the
completeevent when it finishes playing on any Game Object. - The Animation Component has a new method called
chainwhich 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 itsanimationcompletecallback). 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.drawFrameis a new method that allows you to draw a texture frame to the CanvasTexture based on the texture key and frame given.CanvasTexture.getIndexis a new method that will take an x/y coordinate and return the Image Data index offset used to retrieve the pixel values.CanvasTexture.getPixelsis 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.setPixelis a new method that sets the given pixel in the CanvasTexture to the color and alpha values provided.CanvasTexture.getDatais a new method that will extract an ImageData block from the CanvasTexture from the region given.CanvasTexture.putDatais a new method that will put an ImageData block at the given coordinates in a CanvasTexture.Line.Extendis a new static function that allows you extend the start and/or end points of a Line by the given amounts.Vector2.LEFTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.RIGHTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.UPis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.DOWNis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector2.ONEis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.ZEROis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.LEFTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.RIGHTis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.UPis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.DOWNis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.FORWARDis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.BACKis a new constant that can be used in Vector comparison operations (thanks @Aedalus)Vector3.ONEis a new constant that can be used in Vector comparison operations (thanks @Aedalus)- Geometery Mask has a new property called
invertAlphain 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
maxSpeedwhich limits the vector length of the Body velocity. You can set it via the methodsetMaxSpeedand it is applied in theWorld.computeVelocitymethod (thanks @Edwin222 @rexrainbow) WebGLRenderer.snapshotAreais 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 assnapshotexcept you control the area being grabbed, so is more efficient if you only need a smaller area.WebGLRenderer.snapshotPixelis a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as aColorobject to your specified callback.CanvasRenderer.snapshotAreais 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 assnapshotexcept you control the area being grabbed, so is more efficient if you only need a smaller area.CanvasRenderer.snapshotPixelis a new method that allows you to grab a single pixel from the game canvas, post-render. It returns the result as aColorobject to your specified callback.
Updates
- You can now modify
this.physics.world.debugGraphic.defaultStrokeWidthto set the stroke width of any debug drawn body, previously it was always 1 (thanks @samme) TextStyle.setFonthas a new optional argumentupdateTextwhich will sets if the text should be automatically updated or not (thanks @DotTheGreat)ProcessQueue.destroynow sets the internaltoProcesscounter to zero.- The
PathFollower.pathRotationVerticalAdjustproperty 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. TheverticalAdjustargument from thesetRotateToPathmethod has been removed as well. - The config value
preserveDrawingBufferhas been removed as it has never been used by the WebGL Renderer. PluginManager.installreturnsnullif the plugin failed to install in all cases.PluginFilewill now install the plugin into the current Scene as long as thestartormappingarguments 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
callbackDataobject instead, like the WebGL renderer does. WebGLRenderer.setBlendModehas a new optional argumentforce, which will force the given blend mode to be set, regardless of the current settings.- The method
DisplayList.sortGameObjectshas 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.getTopGameObjecthas 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.setFramebufferhas a new optional boolean argumentupdateScissor, which will reset the scissor to match the framebuffer size, or clear it.WebAudioSoundManager.onFocuswill not try to resume the Audio Context if it's still locked.WebAudioSoundManager.onBlurwill 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.strokeis a new alias for thestrokePathmethod, to keep the calls consistent with the Canvas Rendering Context API.Graphics.fillis a new alias for thefillPathmethod, to keep the calls consistent with the Canvas Rendering Context API.LoaderPlugin.sceneManageris a new property that is a reference to the global Scene Manager, useful for Plugins.- Whenever
Camera.roundPixelswas 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 toMath.roundinstead. 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.createwill now return a booleanfalseif the given key is invalid (i.e. undefined or falsey).AnimationManager.createwill 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, theaddevent is emitted by the Animation Manager. If no event is emitted, the animation already existed.ArcadePhysics.Body.destroywill now only add itself to the WorldpendingDestroylist if the world property exists. This preventsCannot read property 'pendingDestroy' of undefinederrors 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
restartmethod has had is solekeyargument 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.playandplayReversewill 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.clearnow has 4 new optional arguments:x, y, width, heightwhich 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.batchQuadandbatchTrihave two new optional argumentstextureandunitwhich are used to re-set the batch texture should the method cause a batch flush.TextureTintPipeline.requireTextureBatchis a new internal method that helps speed-up the creation of texture batches. It is used in conjunction withsetTexture2DandpushBatch.TextureTintPipeline.flushandTextureTintPipeline.pushBatchhave been optimized to handle zero based texture units as priority. They've also been refactored to avoid creation of empty texture batches.- The
WebGLRenderer.setTexture2Dmethod has a new optional argumentflushwhich 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
widthandheightproperties are now based on the tilemap tile sizes multiplied by the layer dimensions. This corrects an issue with layer sizes being wrong if you calledsetBaseTileSizeon a Map. - The WebGLRenderer will now clear the framebuffer at the start of every render.
WebGLRenderer.setScissornow has a new optional argumentdrawingBufferHeightwhich allows you to specify the drawing buffer height, rather than use the renderers default value.WebGLRenderer.pushScissornow has a new optional argumentdrawingBufferHeightwhich allows you to specify the drawing buffer height, rather than use the renderers default value.WebGLRenderer.preRendernow callsgl.clearColorin order to restore the background clear color in case something, like a Render Texture, has changed it.Map.setwill 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.MatterSpritewould set itstypeproperty to beImage. It now sets it to beSpriteas it should do.Matter.TileBody.setFromTileCollisionno 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
transitionstartevent is now dispatched by the Target Scene of a transition, regardless if the Scene has acreatemethod 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.restartnow returns the Tween instance (thanks @rexrainbow)Tween.playnow returns the Tween instance (thanks @rexrainbow)Tween.seeknow returns the Tween instance (thanks @rexrainbow)Tween.completenow returns the Tween instance (thanks @rexrainbow)Tween.stopnow returns the Tween instance (thanks @rexrainbow)List.sortnow has an optional parameterhandlerwhich allows you to provide your own sort handling function (thanks @jcyuan)Container.sortnow has an optional parameterhandlerwhich allows you to provide your own sort handling function (thanks @jcyuan)- The WebGLRenderer method
canvasToTexturewill now only set the filter to beNEARESTifantialiasis 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 callingtexture.setFilter(1)on them. CanvasRenderer.snapshotCallback,snapshotTypeandsnapshotEncoderhave all been removed as they are no longer required.CanvasRenderer.snapshotStateis a new object that contains the snapshot configuration data, the same as the WebGL Renderer.- The signature of the
WebGLSnapshotfunction has changed. It now takes a Snapshot Configuration object as the second parameter. - The signature of the
CanvasSnapshotfunction 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,fontSizeandfontStylein eitherText.setStyleorsetFont, 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.toJSONwasn'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 erroras 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.cullmethod 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.ReverseRowswas actually reversing the columns, but now reverses the rows.Array.Matrix.ReverseColumnswas 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
fillRectcalls 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
cameraFilterproperty 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.startFollowmethod now properly uses thestartAtargument 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
HTML5AudioSoundinstance, via themutesetter, now works as it does via the Sound Manager (thanks @Waclaw-I @neon-dev) - Changing the volume on an
HTML5AudioSoundinstance, via thevolumesetter, 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.tilesetnow returns the specific Tileset associated with the tile rather than an array of them. Fix #4095 (thanks @quadrupleslap)Tile.getCollisionGroupwouldn't return the correct Group after the change to support multiple Tilesets. It now returns the group properly (thanks @jbpuryear)Tile.getTileDatawouldn't return the correct data after the change to support multiple Tilesets. It now returns the tile data properly (thanks @jbpuryear)- The
GetTileAtandRemoveTileAtcomponents 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.widthorTileSprite.heightwill now flag the texture as dirty and callupdateDisplayOrigin, allowing you to resize TileSprites dynamically in both Canvas and WebGL. RandomDataGenerator.shufflehas 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.indexSortCallbackhas been removed as it's no longer required.Particle.indexhas 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.resetPositionis a new method that is called when a particle dies preparing it for firing again in the future.- The Canvas
SetTransformmethod 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.MoveUpwouldn't let you move an array element to the top-most index in the array. This also impactedContainer.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
batchQuadandbatchTrimethods 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
scaleXorscaleYon aMatterImageorMatterSpritewould 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.resetin Arcade Physics would ignore thexandyvalues 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, thealphaargument would be ignored in Canvas mode. It's now used when filling the RenderTexture. - Fixed an issue in
WebGLRenderer.setScissorwhere it was possible to try and compare the scissor size to a non-current scissor if called outside of the render loop (i.e. fromRenderTexture.fill) (thanks @hackhat) RenderTexture.fillin WebGL would usegl.clearand 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 thedrawFillRectmethod of the Texture Tint Pipeline, allowing it to work properly regardless of camera zoom or size.Container.getFirstwas using an incorrect Array Utils functionGetFirstElementwhen it should have been usingGetFirst. It now uses the correct function. Fix #4244 (thanks @miran248)List.getFirstwas using an incorrect Array Utils functionGetFirstElementwhen it should have been usingGetFirst. 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.destroyis 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
processDomCallbacksmethod in the Input Manager wasn't correctly clearing theoncearrays. Responsibility for this has now been passed to the queue methodsqueueTouchStart,queueTouchMove,queueTouchEnd,queueMouseDown,queueMouseMoveandqueueMouseUp. Fix #4257 (thanks @iArePJ) - Arcade Physics now manages when
postUpdateshould 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
collideevent on a Body even if it performing an overlap check, if theonCollideproperty 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 = truein the game config (thanks @gomachan7) List.sortwas missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)Container.sortwas missing the scope required for the sort handler, this is now correctly provided internally. Fix #4241 (thanks @jcyuan)DataManager.popwould 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
maxLightsvalue 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.SameDimensionsdetermines 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.setEnableis a new chainable method that allows you to toggle the enable state of an Arcade Physics Body (thanks @samme)KeyboardPlugin.resetKeysis a new method that will reset the state of any Key object created by a Scene's Keyboard Plugin.Pointer.wasCanceledis a new boolean property that allows you to tell if a Pointer was cleared due to atouchcancelevent. This flag is reset during the nexttouchstartevent for the Pointer.Pointer.touchcancelis a new internal method specifically for handling touch cancel events. It has the same result astouchendwithout setting any of the up properties, to avoid triggering up event handlers. It will also set thewasCanceledproperty totrue.
Updates
WebGLRenderer.deleteTexturewill 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 stopRENDER WARNING: there is no texture bound to the unit 0errors if you destroy a Game Object, such as Text or TileSprite, from an async or timed process (thanks jamespierce)- The
RequestAnimationFrame.stepandstepTimeoutfunctions 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.setFramehas had both theupdateSizeandupdateOriginarguments removed as they didn't do anything for TileSprites and were misleading.CameraManager.removehas a new argumentrunDestroywhich, if set, will automatically callCamera.destroyon 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
canvasToTexturehas a new optional argumentnoRepeatwhich will stop it from usinggl.REPEATentirely. 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.resetKeysis now called automatically as part of the Keyboard Pluginshutdownmethod. 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 Managerhas 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_CANCELwhich 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
pixelArtto true in your game config (orantialiasto 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
setBlendModeto stop warnings from being thrown if you added an emitter to a Container in the Canvas renderer. Fix #4083 (thanks @maximtsai) - The
game.contextproperty would be incorrectly set tonullafter the WebGLRenderer instance was created (thanks @samme) - The Touch Manager, Input Manager and Pointer classes all now handle the
touchcancelevent, 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
maxLightsvalue 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.SameDimensionsdetermines 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.setEnableis a new chainable method that allows you to toggle the enable state of an Arcade Physics Body (thanks @samme)KeyboardPlugin.resetKeysis a new method that will reset the state of any Key object created by a Scene's Keyboard Plugin.Pointer.wasCanceledis a new boolean property that allows you to tell if a Pointer was cleared due to atouchcancelevent. This flag is reset during the nexttouchstartevent for the Pointer.Pointer.touchcancelis a new internal method specifically for handling touch cancel events. It has the same result astouchendwithout setting any of the up properties, to avoid triggering up event handlers. It will also set thewasCanceledproperty totrue.
Updates
WebGLRenderer.deleteTexturewill 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 stopRENDER WARNING: there is no texture bound to the unit 0errors if you destroy a Game Object, such as Text or TileSprite, from an async or timed process (thanks jamespierce)- The
RequestAnimationFrame.stepandstepTimeoutfunctions 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.setFramehas had both theupdateSizeandupdateOriginarguments removed as they didn't do anything for TileSprites and were misleading.CameraManager.removehas a new argumentrunDestroywhich, if set, will automatically callCamera.destroyon 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
canvasToTexturehas a new optional argumentnoRepeatwhich will stop it from usinggl.REPEATentirely. 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.resetKeysis now called automatically as part of the Keyboard Pluginshutdownmethod. 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 Managerhas 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_CANCELwhich 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
pixelArtto true in your game config (orantialiasto 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
setBlendModeto stop warnings from being thrown if you added an emitter to a Container in the Canvas renderer. Fix #4083 (thanks @maximtsai) - The
game.contextproperty would be incorrectly set tonullafter the WebGLRenderer instance was created (thanks @samme) - The Touch Manager, Input Manager and Pointer classes all now handle the
touchcancelevent, 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
createStaticLayerandcreateDynamicLayermethods respectively. Tilemap.createStaticLayernow 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.createDynamicLayernow 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.createBlankDynamicLayernow 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.getTilesetis a new method that will return a Tileset based on its name.ParseTilesetshas 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.setBaseTileSizenow sets the size into the LayerDatabaseTileWidthandbaseTileHeightproperties accordingly. Fix #4057 (thanks @imilo)- Calling
Tilemap.renderDebugignored 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.renderDebugignored 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.tilesetis now an array of Tileset objects, where-as before it was a single reference.StaticTilemapLayer.vertexBufferis now an array of WebGLBuffer objects, where-as before it was a single instance.StaticTilemapLayer.bufferDatais now an array of ArrayBuffer objects, where-as before it was a single instance.StaticTilemapLayer.vertexViewF32is now an array of Float3Array objects, where-as before it was a single instance.StaticTilemapLayer.vertexViewU32is now an array of Uint32Array objects, where-as before it was a single instance.StaticTilemapLayer.dirtyis now an array of booleans, where-as before it was a single boolean.StaticTilemapLayer.vertextCountis 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 parametertilesetIndexwhich controls which tileset to prepare the VBO data for. - The
StaticTilemapLayer.batchTile()method has a new parametertilesetIndexwhich controls which tileset to batch the tile for. StaticTilemapLayer.setTilesets()is a new private method that creates the internal tileset references array.DynamicTilemapLayer.tilesetis 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
bodyDebugFillColoris a new Matter Physics debug option that allows you to set a color used when drawing filled bodies to the debug Graphic.debugWireframesis 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 istrue. If enabled bodies are not filled.debugShowInternalEdgesis a new Matter Physics debug option that allows you to set if the internal edges of a body are rendered to the debug Graphic.debugShowConvexHullsis 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 isfalse.debugConvexHullColoris a new Matter Physics debug option that lets you set the color of the convex hull, if being drawn to the debug Graphic.debugShowSleepingis a new Matter Physics debug option that lets you draw sleeping bodies at 50% opacity.Curves.Ellipse.angleis 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.setTocan 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-decomplibrary, as used by Matter.js, has been updated to 0.3.0. Matter.verts, available viathis.matter.vertsfrom within a Scene, is a quick way of accessing the Matter Vertices functions.- You can now specify the vertices for a Matter
fromVertsbody as a string. TextureTintPipeline.batchTexturehas a new optional argumentskipFlipwhich allows you to control the internal render texture flip Y check.- The Device.OS check for
nodewill now do atypeoffirst 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
updateBoundscall. 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 usingsetOffset, 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.getFramesFromTextureSourcemethod has a new boolean argumentincludeBase, which defaults tofalseand 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,animationupdateandanimationcomplete. Curves.Ellipse.rotationis 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.sizewill 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
shutdownwill 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.setFontStyleandText.setStrokewill 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
shutdownevent at all (thanks Vitali) - Sprites now have
preDestroymethod, which is called automatically bydestroy. The method destroys the Animation component, unregistering theremoveevent in the process and freeing-up resources. Fix #4051 (thanks @Aveyder) UpdateList.shutdownwasn'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.Lineobject was missing alineWidthproperty unless you called thesetLineWidthmethod, causing the line to not render in Canvas only. Fix #4068 (thanks @netgfx) - All parts of Matter Body now have the
gameObjectproperty set correctly. Previously only the first part of the Body did. - When using
MatterGameObjectandfromVertsas the shape type it wouldn't pass the values toBodies.fromVerticesbecause of a previous conditional. It now passes them over correctly and the body is only set if the result is valid. - The
Texture.getFramesFromTextureSourcemethod was returning an array of Frame names by mistake, instead of Frame references. It now returns the Frames themselves. - When using
CanvasTexture.refreshorGraphics.generateTextureit 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
batchSpritemethods 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
autoResizewas set totruein the game config. Fix #4066 (thanks @Quinten @hsan999) - If a Game instance is destroyed without using the
removeCanvasargument, it would throw exceptions in theMouseManagerafter 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 thebatchFillTrianglemethod 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
pointerdowncallback signature has changed. It used to sendpointer, x, y, camerato the listener. It now sendspointer, x, y, eventto the listener. If you still need thecameraproperty you can get it frompointer.camera. - The Game Object
gameobjectdowncallback signature has a new argument. It now sendseventas the 3rd argument. - The
pointerdownevent, as dispatched by the InputPlugin, is now sent after the Game Object specific events (GameObject.pointerdownandgameobjectdown). This gives you the chance to cancel the event before the global listener receives it. - The Game Object
pointerupcallback signature has a new argument. It now sends theeventas the 4th argument. - The Game Object
gameobjectupcallback signature has a new argument. It now sendseventas the 3rd argument. - The
pointerupevent, as dispatched by the InputPlugin, is now sent after the Game Object specific events (GameObject.pointerupandgameobjectup). This gives you the chance to cancel the event before the global listener receives it. - The Game Object
pointermovecallback signature has a new argument. It now sends theeventas the 4th argument. - The Game Object
gameobjectmovecallback signature has a new argument. It now sendseventas the 3rd argument. - The
pointermoveevent, as dispatched by the InputPlugin, is now sent after the Game Object specific events (GameObject.pointermoveandgameobjectmove). This gives you the chance to cancel the event before the global listener receives it. - The Game Object
pointerovercallback signature has a new argument. It now sends theeventas the 4th argument. - The Game Object
gameobjectovercallback signature has a new argument. It now sendseventas the 3rd argument. - The
pointeroverevent, as dispatched by the InputPlugin, is now sent after the Game Object specific events (GameObject.pointeroverandgameobjectover). This gives you the chance to cancel the event before the global listener receives it. - The Game Object
pointeroutcallback signature has a new argument. It now sends theeventas the 2nd argument. - The Game Object
gameobjectoutcallback signature has a new argument. It now sendseventas the 3rd argument. - The
pointeroutevent, as dispatched by the InputPlugin, is now sent after the Game Object specific events (GameObject.pointeroutandgameobjectout). 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,_pendingRemovaland_pendingInsertionlists on shutdown. Before, it would only clear_list. GameObject.destroyhas a new optional boolean argumentfromScene, 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.setRenderToTextureis 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.clearRenderToTextureis a new method that stops a Camera from rendering to a texture and frees-up all associated resources.Camera.setPipelineallows 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.renderToTextureis a boolean property that controls where the Camera renders. It can be toggled on the fly.Camera.canvasis a Canvas Element that the Camera will render to if running under the Canvas Renderer and rendering to a texture.Camera.contextis a Rendering Context that the Camera will render to if running under the Canvas Renderer and rendering to a texture.Camera.glTextureis a WebGL Texture that the Camera will render to if running under the WebGL Renderer and rendering to a texture.Camera.framebufferis a WebGL Frame Buffer that the Camera will render to if running under the WebGL Renderer and rendering to a texture.Camera.pipelineis 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 eventpostrender. 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
Colorobject has a new propertyhwhich 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
Colorobject has a new propertyswhich 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
Colorobject has a new propertyvwhich 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.setFromHSVis a new method that will set the color values based on the HSV values given.Color.grayis a new method that will set the color to be a shade of gray based on the amount given.Color.randomis a new method that will set the color to be a random hue based on the min and max values given.Color.randomGrayis a new method that will set the color to be a random grayscale based on the min and max values given.Color.saturateis 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.desaturateis 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.lightenis 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.darkenis 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.brightenis a new method that will brighten the color based on the amount given.- The
CanvasTextureclass has a new propertyimageDatawhich contains the ImageData of the texture. - The
CanvasTextureclass has a new propertydatawhich is a Uint8ClampedArray view into thebuffer. - The
CanvasTextureclass has a new propertypixelswhich is a Uint32Array view into thebuffer. - The
CanvasTextureclass has a new propertybufferwhich is an ArrayBuffer the same size as the context ImageData. - The
CanvasTextureclass has a new methodupdatewhich refreshes the ImageData and ArrayBuffer based on the texture contents. - The
CanvasTextureclass has a new methoddrawwhich draws the given Image or Canvas element to the CanvasTexture, then updates the internal ImageData buffer and arrays. - The
CanvasTextureclass has a new methodgetPixelwhich 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
setFloat1vwhich allows you to set auniform1fvuniform value (thanks @Mattykins) - The WebGLPipeline and WebGLRenderer have new a method
setFloat2vwhich allows you to set auniform2fvuniform value (thanks @Mattykins) - The WebGLPipeline and WebGLRenderer have new a method
setFloat3vwhich allows you to set auniform3fvuniform value (thanks @Mattykins) - The WebGLPipeline and WebGLRenderer have new a method
setFloat4vwhich allows you to set auniform4fvuniform value (thanks @Mattykins) Text.setLineSpacingis 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
beginPathon 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 callingGraphics.clear. initPipelinenow 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
RGBToHSVfunction can now take an optionaloutargument, which is either aHSVColorObjector aColorobject, and the results will be set into that object instead of creating a new one. - The
HSVToRGBfunction can now take an optionaloutargument, which is either aHSVColorObjector aColorobject, and the results will be set into that object instead of creating a new one. Color.setTohas a new argumentupdateHSVwhich allows you to control if the internal HSV values are updated during the same call or not.- The
Text._lineSpacingproperty has been renamed tolineSpacingand made public, not private. You still set it in the same way, by passing alineSpacingproperty to the Text configuration object, but internally it's now clearer. - If a Scene is already active (i.e. running) and you call
starton 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.setStylewould make the Text vanish if you didn't provide aresolutionproperty in the style configuration object. CallingsetStylenow 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.visibleproperty set tofalseit 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
pausedin its config, never started it, and then calledTween.stopit wouldn't ever be removed from the_pendingarray. 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
shutdownevent 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
setScenemethod, which is called automatically when a new Camera is created, will now callupdateSystemwhich 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
setRenderToTextureenabled 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.resizewouldn't correctly resize the texture under WebGL. Fix #4034 (thanks @jbpuryear)- Calling
setFrameon a TileSprite wouldn't change the frame, it would just change the frame size. Fix #4039 (thanks @Jerenaux) Zone.setRectangleDropZoneused the wrongxandycoordinates 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
batchTrimethod will add a triangle to the vertex batch, either textured or filled. drawFillRectis a new method that will add an untransformed rectangle to the batch. These are used by things like Cameras to fill in background colors.batchFillRecthas been moved to the TextureTintPipeline and has a new much more concise method signature.batchFillTrianglehas been moved to the TextureTintPipeline and has a new much more concise method signature.batchFillPathhas been moved to the TextureTintPipeline and has a new much more concise method signature.batchLinehas 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
updateSystemwhich 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
drawmethod 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.childrento 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
drawFramewhich allows you to pass in a string-based texture and frame key and have it drawn to the Render Texture.The new method
saveTextureallows 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 theRenderTexture.texture.addmethod.The new
cameraproperty 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
setCropmethod 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
setCropmethod to crop the text. - Text now keeps a reference to the renderer in the
rendererproperty. - The
canvasTextureproperty has been removed. - Text now has internal
textureandframeproperties. These replace the oldcanvasTexturebut perform the same task, while allowing for texture cropping and much smaller renderer code. - Previously, changing a Text object by setting its
textproperty directly wouldn't change the text being rendered as usingsetTextwas the expected way to change what was being displayed. Internally thetextproperty has been renamed to_textand flagged as private, and a new getter / setter fortexthas been added, which hands over to thesetTextmethod, 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
setCropmethod to crop the tile sprite. - There is a new method
setTileScalewhich will set the tile scale in a chainable call. - There is a new internal
canvasproperty. Tile Sprites work differently than before in Canvas mode: Previously they would use thefillRectcommand 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
_tilePositionand_tileScalewhich 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
displayTextureanddisplayFrame. These replace the previoustextureandframeproperties and hold references to the source texture the Tile Sprite is using. - The
canvasPatternproperty has been renamed tofillPattern. - The
oldFrameproperty has been removed. - The
canvasBufferproperty has been renamed tofillCanvas. - The
canvasBufferCtxproperty has been renamed tofillContext.
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
renderOrderwhich 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
renderorderproperty from the Tiled JSON. - MapData has a new
renderOrderproperty, 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
pointargument 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.addit is now added to the Display and Update Lists. Fix #3945 (thanks @vvega)
New Features
Camera.resolutionis 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.resolutionand the methodText.setResolutionallows 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.getCSSMatrixwill return a CSS transform matrix formatted string from the current matrix values.CacheManagernow creates a new cache calledhtmlwhich is used to store all loaded HTML snippets.FileType.HTMLis a new file type loader that will load an HTML snippet and store it in the newhtmlcache. Access it viaload.html(this method was previously used to load html to textures, please seeload.htmlTexturefor this feature now)TransformMatrix.getXis 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.getYis 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.copyToArrayis a new method that will copy the matrix values to the given array. It's the counter-part ofcopyFromArray.Graphics.setTextureis 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.fillGradientStyleis 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.lineGradientStyleis 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.getBase64is 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
dataobject, the contents of which are passed to the pluginsinitmethod. 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 theinstallmethod (thanks @samme) - You can now play animations in reverse! Use the new
Sprite.anims.playReversemethod to play a pre-defined animation in reverse from its starting frame. Or callSprite.anims.reverseto 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
ParticleEmitterManagernow 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.addRenderTextureis 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
isRenderTexturewhich is set automatically when it's created. - The Canvas Renderer has a new method
setContextwhich 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_WEBGLorwindow.FORCE_CANVASin 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.sourceis a new property that contains the original source of the Texture image. It is cleared when the source is destroyed.TransformMatrix.copyToContextis a new method that will copy the values from the Matrix to the given Canvas Rendering Context.Phaser.Utils.String.UUIDwill 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
CropComponent which is used by non-texture based Game Objects, such as Text and TileSprite. You either useTextureCroporCrop, not both together on the same object. TransformMatrix.setToContextis a new method that will set the values from the Matrix to the given Canvas Rendering Context using setTransform rather than transform.SetTransformis 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
renameTexturewhich 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.Perimeterwill return the perimeter for the given Polygon (thanks @iamchristopher)Polygon.GetPointswill 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 thegetPointsmethod on a Polygon (thanks @iamchristopher)
Updates
- The Camera class has been split into two:
BaseCamerawhich 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, andCamerawhich is the same class name as previously.Cameraextends 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.xandCamera.yhave been turned into getters / setters, mapped to the internal private values_xand_yrespectively. This is so that setting the Camera viewport position directly will now update the new internal resolution calculation vars too.Camera.setScenewill now set the Camerasresolutionproperty at the same time and update the internal viewport vars.- The
Cull Tilesmethod 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.willRendernow 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
HTMLhas been renamed toHTMLTexture. If you were using this then please change your calls fromload.htmltoload.htmlTexture. The arguments remain the same. - The
setBlendModemethod 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
batchVerticesin the TextureTintPipeline has been renamed tobatchQuadwhich more accurately describes what it does. - In ArcadePhysics
Body.setSizeyou 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.destroyCorePluginswill 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.destroyCustomPluginswill remove all custom plugins from the cache.PluginManager.destroywill 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.destroyhas a new boolean argumentnoReturn. 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
MouseManagerwill 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
TouchManagerwill 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.colorhas 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
texturesreadyevent, which is dispatched by the Texture Manager when the default textures have finished processing. Upon receiving this, the Game will emit thereadyevent, which all the other systems listen for and respond to. The difference is that the Renderer uses thetexturesreadyevent to ensure that it is the first thing to be activated, before any other system. - The WebGLRenderer has a new property
blankTexturewhich 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
setBlankTexturewhich 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,setSkipCullandsetCullPaddingas 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.CeilandSnap.Tohave all gained a new optional boolean argumentdivide. 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
currentBlendModeproperty 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
currentAlphaproperty 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. TextureCropandCrophave a new methodresetCropObjectwhich 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
batchSpritemethod 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
batchTexturemethod in the Texture Tint Pipeline now supports cropped Game Objects and will adjust the drawn texture frame accordingly. - The
Matrix StackComponent has been removed. It's no longer used internally and was just wasting space. - You can now specify the
lineHeightof 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
roundPixelsvalue to clamp the tile coordinates. - The
CanvasRenderer.DrawImagefunction has been removed, as has the associateddrawImageproperty from the Canvas Renderer as they're no longer used. - The
CanvasRenderer.BlitImagefunction has been removed, as has the associatedblitImageproperty from the Canvas Renderer as they're no longer used. - You can now access the Game instance directly from a Scene using
this.gameas 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.ignorecan now take nested-arrays of Game Objects and also supports both Groups and Containers.- The
changedataevent 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.clearColoris now skipped whenclearBeforeRenderis set tofalse(thanks @goldfire) - The calls to
DistanceBetweenhave been replaced withDistanceSquaredin theclosestandfurthestfunctions 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
createFromObjectsmethod 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.touchset tofalse(the default was true). If no such property is set, it no longer defaults totrueand instead is set to whateverDevice.input.touchreturns. On non-touchscreen desktops this means it will now only create one single Pointer, rather than two. - The Arcade Physics Body
_tempMatrixproperty 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
_tempMatrixand_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
applyInversewhich 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.addKeyswill now trim the input allowing you to space characters out if you prefer (thanks @dhruvyad) - Calling
setTimeScaleon 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
resolutionwas > 1. These are now factored in correctly and changing the resolution no longer breaks input. Fix #3606 (thanks @Secretmapper @thanh-taro)
Bug Fixes
- The
setCropmethod 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.closestandArcadePhysics.furthestused the wrong tree reference, causing them to throw errors (thanks @samme)BlitterCanvasRendererwould fail to render a Bob in Canvas mode if it was flipped (thanks @SBCGames)RenderTexture.drawwould fail to draw the frame in Canvas mode (thanks @SBCGames)ParticleEmitterwould fail to draw a textured particle in Canvas mode (thanks @SBCGames)RenderTexture.preDestroywill now release the canvas back to the CanvasPool if running in canvas mode (thanks @SBCGames)- The
alphavalue is now always set for Render Textures in canvas mode, regardless of the previous alpha value in the renderer (thanks @SBCGames) - Zone now calls
updateDisplayOriginin its constructor, causing thedisplayOriginXanddisplayOriginYvalues to now be correct if you create a Zone and then don't resize it. Fix #3865 (thanks @rexrainbow) - The
CameraManagerwas accidentally adding extra destroy event calls when a Scene was restarted, causing anUncaught TypeError: Cannot read property 'events' of nullwhen 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
CullTilesupdates 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
collisionEndfrom 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.speedproperty is now set whenever you set the velocity viasetVelocityorsetVelocityXorsetVelocityYwhich stops the body velocity being reset to zero ifuseDampingis enabled. Fix #3888 (thanks @samme) - The
getPixelAlphamethod in the Texture Manager wasn't using the correct frame name. This is now passed in correctly. Fix #3937 (thanks @goldfire) - The
getPixelAlphaandgetPixelmethods 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_TESTset by using the getter or thesetBlendModemethod. - In Arcade Physics the
World.disablecall 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
overshootargument 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.inputCandidatemethod, 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.getWorldTransformMatrixhas 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
collideduring anupdatemethod 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
setTintFillmethod would ignore thealphavalue 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
collideSpriteVsTilemapLayernow syncs the collision results back to the body, allowing you to callcollidefrom within an update loop once again. Fix #3999 (thanks @nkholski @mikewesthad) - Arcade Physics Body
deltaXanddeltaYmethods 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
batchTrimethod will add a triangle to the vertex batch, either textured or filled. drawFillRectis a new method that will add an untransformed rectangle to the batch. These are used by things like Cameras to fill in background colors.batchFillRecthas been moved to the TextureTintPipeline and has a new much more concise method signature.batchFillTrianglehas been moved to the TextureTintPipeline and has a new much more concise method signature.batchFillPathhas been moved to the TextureTintPipeline and has a new much more concise method signature.batchLinehas 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
updateSystemwhich 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
drawmethod 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.childrento 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
drawFramewhich allows you to pass in a string-based texture and frame key and have it drawn to the Render Texture.The new method
saveTextureallows 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 theRenderTexture.texture.addmethod.The new
cameraproperty 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
setCropmethod 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
setCropmethod to crop the text. - Text now keeps a reference to the renderer in the
rendererproperty. - The
canvasTextureproperty has been removed. - Text now has internal
textureandframeproperties. These replace the oldcanvasTexturebut perform the same task, while allowing for texture cropping and much smaller renderer code. - Previously, changing a Text object by setting its
textproperty directly wouldn't change the text being rendered as usingsetTextwas the expected way to change what was being displayed. Internally thetextproperty has been renamed to_textand flagged as private, and a new getter / setter fortexthas been added, which hands over to thesetTextmethod, 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
setCropmethod to crop the tile sprite. - There is a new method
setTileScalewhich will set the tile scale in a chainable call. - There is a new internal
canvasproperty. Tile Sprites work differently than before in Canvas mode: Previously they would use thefillRectcommand 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
_tilePositionand_tileScalewhich 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
displayTextureanddisplayFrame. These replace the previoustextureandframeproperties and hold references to the source texture the Tile Sprite is using. - The
canvasPatternproperty has been renamed tofillPattern. - The
oldFrameproperty has been removed. - The
canvasBufferproperty has been renamed tofillCanvas. - The
canvasBufferCtxproperty has been renamed tofillContext.
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
renderOrderwhich 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
renderorderproperty from the Tiled JSON. - MapData has a new
renderOrderproperty, 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
pointargument 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.addit is now added to the Display and Update Lists. Fix #3945 (thanks @vvega)
New Features
Camera.resolutionis 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.resolutionand the methodText.setResolutionallows 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.getCSSMatrixwill return a CSS transform matrix formatted string from the current matrix values.CacheManagernow creates a new cache calledhtmlwhich is used to store all loaded HTML snippets.FileType.HTMLis a new file type loader that will load an HTML snippet and store it in the newhtmlcache. Access it viaload.html(this method was previously used to load html to textures, please seeload.htmlTexturefor this feature now)TransformMatrix.getXis 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.getYis 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.copyToArrayis a new method that will copy the matrix values to the given array. It's the counter-part ofcopyFromArray.Graphics.setTextureis 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.fillGradientStyleis 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.lineGradientStyleis 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.getBase64is 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
dataobject, the contents of which are passed to the pluginsinitmethod. 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 theinstallmethod (thanks @samme) - You can now play animations in reverse! Use the new
Sprite.anims.playReversemethod to play a pre-defined animation in reverse from its starting frame. Or callSprite.anims.reverseto 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
ParticleEmitterManagernow 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.addRenderTextureis 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
isRenderTexturewhich is set automatically when it's created. - The Canvas Renderer has a new method
setContextwhich 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_WEBGLorwindow.FORCE_CANVASin 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.sourceis a new property that contains the original source of the Texture image. It is cleared when the source is destroyed.TransformMatrix.copyToContextis a new method that will copy the values from the Matrix to the given Canvas Rendering Context.Phaser.Utils.String.UUIDwill 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
CropComponent which is used by non-texture based Game Objects, such as Text and TileSprite. You either useTextureCroporCrop, not both together on the same object. TransformMatrix.setToContextis a new method that will set the values from the Matrix to the given Canvas Rendering Context using setTransform rather than transform.SetTransformis 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
renameTexturewhich 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:
BaseCamerawhich 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, andCamerawhich is the same class name as previously.Cameraextends 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.xandCamera.yhave been turned into getters / setters, mapped to the internal private values_xand_yrespectively. This is so that setting the Camera viewport position directly will now update the new internal resolution calculation vars too.Camera.setScenewill now set the Camerasresolutionproperty at the same time and update the internal viewport vars.- The
Cull Tilesmethod 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.willRendernow 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
HTMLhas been renamed toHTMLTexture. If you were using this then please change your calls fromload.htmltoload.htmlTexture. The arguments remain the same. - The
setBlendModemethod 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
batchVerticesin the TextureTintPipeline has been renamed tobatchQuadwhich more accurately describes what it does. - In ArcadePhysics
Body.setSizeyou 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.destroyCorePluginswill 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.destroyCustomPluginswill remove all custom plugins from the cache.PluginManager.destroywill 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.destroyhas a new boolean argumentnoReturn. 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
MouseManagerwill 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
TouchManagerwill 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.colorhas 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
texturesreadyevent, which is dispatched by the Texture Manager when the default textures have finished processing. Upon receiving this, the Game will emit thereadyevent, which all the other systems listen for and respond to. The difference is that the Renderer uses thetexturesreadyevent to ensure that it is the first thing to be activated, before any other system. - The WebGLRenderer has a new property
blankTexturewhich 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
setBlankTexturewhich 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,setSkipCullandsetCullPaddingas 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.CeilandSnap.Tohave all gained a new optional boolean argumentdivide. 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
currentBlendModeproperty 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
currentAlphaproperty 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. TextureCropandCrophave a new methodresetCropObjectwhich 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
batchSpritemethod 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
batchTexturemethod in the Texture Tint Pipeline now supports cropped Game Objects and will adjust the drawn texture frame accordingly. - The
Matrix StackComponent has been removed. It's no longer used internally and was just wasting space. - You can now specify the
lineHeightof 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
roundPixelsvalue to clamp the tile coordinates. - The
CanvasRenderer.DrawImagefunction has been removed, as has the associateddrawImageproperty from the Canvas Renderer as they're no longer used. - The
CanvasRenderer.BlitImagefunction has been removed, as has the associatedblitImageproperty from the Canvas Renderer as they're no longer used. - You can now access the Game instance directly from a Scene using
this.gameas 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.ignorecan now take nested-arrays of Game Objects and also supports both Groups and Containers.- The
changedataevent 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.clearColoris now skipped whenclearBeforeRenderis set tofalse(thanks @goldfire) - The calls to
DistanceBetweenhave been replaced withDistanceSquaredin theclosestandfurthestfunctions 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
createFromObjectsmethod 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.touchset tofalse(the default was true). If no such property is set, it no longer defaults totrueand instead is set to whateverDevice.input.touchreturns. 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
resolutionwas > 1. These are now factored in correctly and changing the resolution no longer breaks input. Fix #3606 (thanks @Secretmapper)
Bug Fixes
- The
setCropmethod 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.closestandArcadePhysics.furthestused the wrong tree reference, causing them to throw errors (thanks @samme)BlitterCanvasRendererwould fail to render a Bob in Canvas mode if it was flipped (thanks @SBCGames)RenderTexture.drawwould fail to draw the frame in Canvas mode (thanks @SBCGames)ParticleEmitterwould fail to draw a textured particle in Canvas mode (thanks @SBCGames)RenderTexture.preDestroywill now release the canvas back to the CanvasPool if running in canvas mode (thanks @SBCGames)- The
alphavalue is now always set for Render Textures in canvas mode, regardless of the previous alpha value in the renderer (thanks @SBCGames) - Zone now calls
updateDisplayOriginin its constructor, causing thedisplayOriginXanddisplayOriginYvalues to now be correct if you create a Zone and then don't resize it. Fix #3865 (thanks @rexrainbow) - The
CameraManagerwas accidentally adding extra destroy event calls when a Scene was restarted, causing anUncaught TypeError: Cannot read property 'events' of nullwhen 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
CullTilesupdates 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
collisionEndfrom 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.speedproperty is now set whenever you set the velocity viasetVelocityorsetVelocityXorsetVelocityYwhich stops the body velocity being reset to zero ifuseDampingis enabled. Fix #3888 (thanks @samme) - The
getPixelAlphamethod in the Texture Manager wasn't using the correct frame name. This is now passed in correctly. Fix #3937 (thanks @goldfire) - The
getPixelAlphaandgetPixelmethods 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_TESTset by using the getter or thesetBlendModemethod. - In Arcade Physics the
World.disablecall 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
overshootargument 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
batchTrimethod will add a triangle to the vertex batch, either textured or filled. drawFillRectis a new method that will add an untransformed rectangle to the batch. These are used by things like Cameras to fill in background colors.batchFillRecthas been moved to the TextureTintPipeline and has a new much more concise method signature.batchFillTrianglehas been moved to the TextureTintPipeline and has a new much more concise method signature.batchFillPathhas been moved to the TextureTintPipeline and has a new much more concise method signature.batchLinehas 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
updateSystemwhich 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
drawmethod 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.childrento 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
drawFramewhich allows you to pass in a string-based texture and frame key and have it drawn to the Render Texture.The new method
saveTextureallows 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 theRenderTexture.texture.addmethod.The new
cameraproperty 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
setCropmethod 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
setCropmethod to crop the text. - Text now keeps a reference to the renderer in the
rendererproperty. - The
canvasTextureproperty has been removed. - Text now has internal
textureandframeproperties. These replace the oldcanvasTexturebut 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
setCropmethod to crop the tile sprite. - There is a new method
setTileScalewhich will set the tile scale in a chainable call. - There is a new internal
canvasproperty. Tile Sprites work differently than before in Canvas mode: Previously they would use thefillRectcommand 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
_tilePositionand_tileScalewhich 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
displayTextureanddisplayFrame. These replace the previoustextureandframeproperties and hold references to the source texture the Tile Sprite is using. - The
canvasPatternproperty has been renamed tofillPattern. - The
oldFrameproperty has been removed. - The
canvasBufferproperty has been renamed tofillCanvas. - The
canvasBufferCtxproperty has been renamed tofillContext.
New Features
Camera.resolutionis 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.resolutionand the methodText.setResolutionallows 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.getCSSMatrixwill return a CSS transform matrix formatted string from the current matrix values.CacheManagernow creates a new cache calledhtmlwhich is used to store all loaded HTML snippets.FileType.HTMLis a new file type loader that will load an HTML snippet and store it in the newhtmlcache. Access it viaload.html(this method was previously used to load html to textures, please seeload.htmlTexturefor this feature now)TransformMatrix.getXis 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.getYis 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.copyToArrayis a new method that will copy the matrix values to the given array. It's the counter-part ofcopyFromArray.Graphics.setTextureis 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.fillGradientStyleis 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.lineGradientStyleis 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.getBase64is 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
dataobject, the contents of which are passed to the pluginsinitmethod. 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 theinstallmethod (thanks @samme) - You can now play animations in reverse! Use the new
Sprite.anims.playReversemethod to play a pre-defined animation in reverse from its starting frame. Or callSprite.anims.reverseto 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
ParticleEmitterManagernow 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.addRenderTextureis 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
isRenderTexturewhich is set automatically when it's created. - The Canvas Renderer has a new method
setContextwhich 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_WEBGLorwindow.FORCE_CANVASin 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.sourceis a new property that contains the original source of the Texture image. It is cleared when the source is destroyed.TransformMatrix.copyToContextis a new method that will copy the values from the Matrix to the given Canvas Rendering Context.Phaser.Utils.String.UUIDwill 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
CropComponent which is used by non-texture based Game Objects, such as Text and TileSprite. You either useTextureCroporCrop, not both together on the same object. TransformMatrix.setToContextis a new method that will set the values from the Matrix to the given Canvas Rendering Context using setTransform rather than transform.SetTransformis 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
renameTexturewhich 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:
BaseCamerawhich 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, andCamerawhich is the same name space as previously.Cameraextends 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.xandCamera.yhave been turned into getters / setters, mapped to the internal private values_xand_yrespectively. This is so that setting the Camera viewport position directly will now update the new internal resolution calculation vars too.Camera.setScenewill now set the Camerasresolutionproperty at the same time and update the internal viewport vars.- The
Cull Tilesmethod 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.willRendernow 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
HTMLhas been renamed toHTMLTexture. If you were using this then please change your calls fromload.htmltoload.htmlTexture. The arguments remain the same. - The
setBlendModemethod 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.htmlmethod has been renamed toload.htmlTexture. - The method
batchVerticesin the TextureTintPipeline has been renamed tobatchQuadwhich more accurately describes what it does. - In ArcadePhysics
Body.setSizeyou 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.destroyCorePluginswill 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.destroyCustomPluginswill remove all custom plugins from the cache.PluginManager.destroywill 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.destroyhas a new boolean argumentnoReturn. 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
MouseManagerwill 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
TouchManagerwill 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.colorhas 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
texturesreadyevent, which is dispatched by the Texture Manager when the default textures have finished processing. Upon receiving this, the Game will emit thereadyevent, which all the other systems listen for and respond to. The difference is that the Renderer uses thetexturesreadyevent to ensure that it is the first thing to be activated, before any other system. - The WebGLRenderer has a new property
blankTexturewhich 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
setBlankTexturewhich 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,setSkipCullandsetCullPaddingas 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.CeilandSnap.Tohave all gained a new optional boolean argumentdivide. 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
currentBlendModeproperty 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
currentAlphaproperty 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. TextureCropandCrophave a new methodresetCropObjectwhich 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
batchSpritemethod 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
batchTexturemethod in the Texture Tint Pipeline now supports cropped Game Objects and will adjust the drawn texture frame accordingly. - The
Matrix StackComponent has been removed. It's no longer used internally and was just wasting space. - You can now specify the
lineHeightof 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
roundPixelsvalue to clamp the tile coordinates. - The
CanvasRenderer.DrawImagefunction has been removed, as has the associateddrawImageproperty from the Canvas Renderer as they're no longer used. - The
CanvasRenderer.BlitImagefunction has been removed, as has the associatedblitImageproperty from the Canvas Renderer as they're no longer used. - You can now access the Game instance directly from a Scene using
this.gameas 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.ignorecan 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
resolutionwas > 1. These are now factored in correctly and changing the resolution no longer breaks input. Fix #3606 (thanks @Secretmapper)
Bug Fixes
- The
setCropmethod 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.closestandArcadePhysics.furthestused the wrong tree reference, causing them to throw errors (thanks @samme)BlitterCanvasRendererwould fail to render a Bob in Canvas mode if it was flipped (thanks @SBCGames)RenderTexture.drawwould fail to draw the frame in Canvas mode (thanks @SBCGames)ParticleEmitterwould fail to draw a textured particle in Canvas mode (thanks @SBCGames)RenderTexture.preDestroywill now release the canvas back to the CanvasPool if running in canvas mode (thanks @SBCGames)- The
alphavalue is now always set for Render Textures in canvas mode, regardless of the previous alpha value in the renderer (thanks @SBCGames) - Zone now calls
updateDisplayOriginin its constructor, causing thedisplayOriginXanddisplayOriginYvalues to now be correct if you create a Zone and then don't resize it. Fix #3865 (thanks @rexrainbow) - The
CameraManagerwas accidentally adding extra destroy event calls when a Scene was restarted, causing anUncaught TypeError: Cannot read property 'events' of nullwhen 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
CullTilesupdates 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
collisionEndfrom 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.speedproperty is now set whenever you set the velocity viasetVelocityorsetVelocityXorsetVelocityYwhich stops the body velocity being reset to zero ifuseDampingis 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