This commit is contained in:
Svipal 2020-08-09 12:13:29 +02:00
parent a72efc8ac8
commit b4a1473fea
315 changed files with 49852 additions and 247213 deletions

View file

@ -1,13 +1,13 @@
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

View file

@ -82,6 +82,7 @@
"no-lonely-if": "error",
"no-mixed-spaces-and-tabs": "error",
"no-plusplus": "off",
"no-prototype-builtins": "off",
"no-trailing-spaces": [ "error", { "skipBlankLines": true, "ignoreComments": true } ],
"no-underscore-dangle": "off",
"no-whitespace-before-property": "error",

View file

@ -22,6 +22,20 @@ Before contributing, please read the [code of conduct](https://github.com/photon
We have a very active [Phaser Support Forum][4]. If you need general support, or are struggling to understand how to do something or need your code checked over, then we would urge you to post it to our forum. There are a lot of friendly devs in there who can help, as well as the core Phaser team, so it's a great place to get support. You're welcome to report bugs directly on GitHub, but for general support we'd always recommend using the forum first.
## Contribute with online one-click setup
You can use Gitpod (a free online VS Code-like IDE) for contributing. With a single click, it will launch a workspace and automatically:
- clone the `phaser` repo.
- install the dependencies.
- run `npm run build`.
- run `npm run watch`.
- clone `phaser-3-examples` and afterwards install dependencies and run `npm start` in there.
So that anyone interested in contributing can start straight away.
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/photonstorm/phaser)
## Making Changes
I'm assuming you already have a recent version of [Node](https://nodejs.org) installed locally and can run `npm`. This guide is tested and works on both Windows 10 and OS X.

13
.gitpod.yml Normal file
View file

@ -0,0 +1,13 @@
tasks:
- init: >
npm install &&
npm run build
command: npm run watch
- init: >
cd ../ &&
git clone https://github.com/photonstorm/phaser3-examples.git &&
cd phaser3-examples &&
npm install && npm start
ports:
- port: 8080
onOpen: open-preview

View file

@ -6,7 +6,7 @@ git:
language: node_js
node_js:
- '9'
- '10'
env:
- TERM=dumb

View file

@ -1,17 +1,280 @@
# Change Log
## Version 3.23 - Ginro - in development
## Version 3.50.0 - Subaru - in development
### WebGL Multi-Texture Rendering
The Texture Tint Pipeline has had its core flow rewritten to eliminate the need for constantly creating `batch` objects. Instead, it now supports the new multi-texture shader, vastly increasing rendering performance, especially on drawcall-bound systems.
All of the internal functions, such as `batchQuad` and `batchSprite` have been updated to use the new method of texture setting. The method signatures all remain the same, unless indicated below.
* `Config.render.maxTextures` is a new game config setting that allows you to control how many texture units will be used in WebGL.
* `WebGL.Utils.checkShaderMax` is a new function, used internally by the renderer, to determine the maximum number of texture units the GPU + browser supports.
* The property `WebGLRenderer.currentActiveTextureUnit` has been renamed to `currentActiveTexture`.
* `WebGLRenderer.startActiveTexture` is a new read-only property contains the current starting active texture unit.
* `WebGLRenderer.maxTextures` is a new read-only property that contains the maximum number of texture units WebGL can use.
* `WebGLRenderer.textureIndexes` is a new read-only array that contains all of the available WebGL texture units.
* `WebGLRenderer.tempTextures` is a new read-only array that contains temporary WebGL textures.
* The `WebGLRenderer.currentTextures` property has been removed, as it's no longer used.
* `TextureSource.glIndex` is a new property that holds the currently assigned texture unit for the Texture Source.
* `TextureSource.glIndexCounter` is a new property that holds the time the index was assigned to the Texture Source.
* `WebGLRenderer.currentTextures` has been removed, as it's no longer used internally.
* `WebGLRenderer.setBlankTexture` no longer has a `force` parameter, as it's set by default.
* The Mesh Game Object WebGL Renderer function has been updated to support multi-texture units.
* The Blitter Game Object WebGL Renderer function has been updated to support multi-texture units.
* The Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
* The Dynamic Bitmap Text Game Object WebGL Renderer function has been updated to support multi-texture units.
* The Particle Emitter Game Object WebGL Renderer function has been updated to support multi-texture units.
* The Texture Tint vertex and fragment shaders have been updated to support the `inTexId` float attribute and dynamic generation.
* The Texture Tint Pipeline has a new attribute, `inTexId` which is a `gl.FLOAT`.
* `TextureTintPipeline.bind` is a new method that sets the `uMainSampler` uniform.
* The `TextureTintPipeline.requireTextureBatch` method has been removed, as it's no longer required.
* The `TextureTintPipeline.pushBatch` method has been removed, as it's no longer required.
* The `TextureTintPipeline.maxQuads` property has been removed, as it's no longer required.
* The `TextureTintPipeline.batches` property has been removed, as it's no longer required.
* `TextureTintPipeline.flush` has been rewritten to support multi-textures.
* `TextureTintPipeline.flush` no longer creates a sub-array if the batch is full, but instead uses `bufferData` for speed.
* `WebGLPipeline.currentUnit` is a new property that holds the most recently assigned texture unit. Treat as read-only.
* `WebGLRenderer.setTextureSource` is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source.
* The `WebGLRenderer.setTexture2D` method has been updated to use the new texture unit assignment. It no longer takes the `textureUnit` or `flush` parameters and these have been removed from its method signature.
* `WebGLRenderer.setTextureZero` is a new method that activates texture zero and binds the given texture to it. Useful for fbo backed game objects.
* `WebGLRenderer.clearTextureZero` is a new method that clears the texture tha was bound to unit zero.
* `WebGLRenderer.textureZero` is a new property that holds the currently bound unit zero texture.
* `WebGLRenderer.normalTexture` is a new property that holds the currently bound normal map (texture unit one).
* `WebGLRenderer.setNormalMap` is a new method that sets the current normal map texture.
* `WebGLRenderer.clearNormalMap` is a new method that clears the current normal map texture.
* `WebGLRenderer.resetTextures` is a new method that flushes the pipeline, resets all textures back to the temporary ones and resets the active texture counter.
* `WebGLPipeline.boot` will now check all of the attributes and store the pointer location within the attribute entry.
* `WebGLPipeline.bind` no longer looks-up and enables every attribute, every frame. Instead it uses the cached pointer location stored in the attribute entry, cutting down on redundant WebGL operations.
* `WebGLRenderer.isNewNormalMap` is a new method that returns a boolean if the given parameters are not currently used.
* `WebGLPipeline.forceZero` is a new property that informs Game Objects if the pipeline requires a zero bound texture unit.
* `WebGLPipeline.setAttribPointers` is a new method that will set the vertex attribute pointers for the pipeline.
* `WebGLRenderer.unbindTextures` is a new method that will activate and then null bind all WebGL textures.
### Forward Diffuse Light Pipeline API Changes
This Light2D pipeline, which is responsible for rendering lights under WebGL, has been rewritten to work with the new Texture Tint Pipeline functions. Lots of redundant code has been removed and the following changes and improvements took place:
* The pipeline now works with Game Objects that do not have a normal map. They will be rendered using the new default normal map, which allows for a flat light effect to pass over them and merge with their diffuse map colors.
* Fixed a bug in the way lights were handled that caused Tilemaps to render one tile at a time, causing massive slow down. They're now batched properly, making a combination of lights and tilemaps possible again.
* The Bitmap Text (Static and Dynamic) Game Objects now support rendering with normal maps.
* The TileSprite Game Objects now support rendering with normal maps.
* Mesh and Quad Game Objects now support rendering with normal maps.
* The Graphics Game Objects now support rendering in Light2d. You can even use normal map textures for the texture fills.
* Particle Emitter Game Object now supports rendering in Light2d.
* All Shape Game Objects (Rectangle, IsoBox, Star, Polygon, etc) now support rendering in Light2d.
* The Text Game Object now supports rendering in Light2d, no matter which font, stroke or style it is using.
* Both Static and Dynamic Tilemap Layer Game Objects now support the Light2d pipeline, with or without normal maps.
* The pipeline will no longer look-up and set all of the light uniforms unless the `Light` is dirty.
* The pipeline will no longer reset all of the lights unless the quantity of lights has changed.
* The `ForwardDiffuseLightPipeline.defaultNormalMap` property has changed, it's now an object with a `glTexture` property that maps to the pipelines default normal map.
* The `ForwardDiffuseLightPipeline.boot` method has been changed to now generate a default normal map.
* The `ForwardDiffuseLightPipeline.onBind` method has been removed as it's no longer required.
* The `ForwardDiffuseLightPipeline.setNormalMap` method has been removed as it's no longer required.
* `ForwardDiffuseLightPipeline.bind` is a new method that handles setting-up the shader uniforms.
* The `ForwardDiffuseLightPipeline.batchTexture` method has been rewritten to use the Texture Tint Pipeline function instead.
* The `ForwardDiffuseLightPipeline.batchSprite` method has been rewritten to use the Texture Tint Pipeline function instead.
* `ForwardDiffuseLightPipeline.lightCount` is a new property that stores the previous number of lights rendered.
* `ForwardDiffuseLightPipeline.getNormalMap` is a new method that will look-up and return a normal map for the given object.
### Lights
* `Light.dirty` is a new property that controls if the light is dirty, or not, and needs its uniforms updating.
* `Light` has been recoded so that all of its properties are now setters that activate its `dirty` flag.
* `LightsManager.destroy` will now clear the `lightPool` array when destroyed, where-as previously it didn't.
* `LightsManager.cull` now takes the viewport height from the renderer instead of the game config (thanks zenwaichi)
### WebGL ModelViewProjection API Changes
The `ModelViewProjection` object contained a lot of functions that Phaser never used internally. These have now been
moved to external functions, which can be easily excluded from Custom builds to save space.
If you used any of them in your code, please update to the new function names below:
* `Phaser.Renderer.WebGL.MVP` is a new namespace under which the Model View Projection functions now live.
* `projIdentity` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.ProjectIdentity`
* `projPersp` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.ProjectPerspective`
* `modelRotateX` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.RotateX`
* `modelRotateY` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.RotateY`
* `modelRotateZ` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.RotateZ`
* `viewLoad` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.ViewLoad`
* `viewRotateX` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.ViewRotateX`
* `viewRotateY` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.ViewRotateY`
* `viewRotateZ` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.ViewRotateZ`
* `viewScale` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.ViewScale`
* `viewTranslate` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.ViewTranslate`
* `modelIdentity` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.Identity`
* `modelScale` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.Scale`
* `modelTranslate` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.Translate`
* `viewIdentity` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.ViewIdentity`
* `viewLoad2D` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.ViewLoad2D`
* `projOrtho` is now available as a stand-alone function `Phaser.Renderer.WebGL.MVP.ProjectOrtho`
* `Phaser.Renderer.WebGL.MVP.SetIdentity` is a new function the others use, to save on space.
### BitmapText New Features, Updates and API Changes
* `BitmapText.setCharacterTint` is a new method that allows you to set a tint color (either additive, or fill) on a specific range of characters within a static Bitmap Text. You can specify the start and length offsets and a per-corner tint color.
* `BitmapText.setWordTint` is a new method that allows you to set a tint color (either additive, or fill) on all matching words within a static Bitmap Text. You can specify the word by string, or numeric offset, and the number of replacements to tint.
* `BitmapText.setDropShadow` is a new method that allows you to apply a drop shadow effect to a Bitmap Text object. You can set the horizontal and vertical offset of the shadow, as well as the color and alpha levels. Call this method with no parameters to clear a shadow.
* `BitmapTextWebGLRenderer` has been rewritten from scratch to make use of the new pre-cached WebGL uv texture and character location data generated by `GetBitmapTextSize`. This has reduced the number of calculations made in the function dramatically, as it no longer has work out glyph advancing or offsets during render, but only when the text content updates.
* `BitmapText.getCharacterAt` is a new method that will return the character data from the BitmapText at the given `x` and `y` corodinates. The character data includes the code, position, dimensions and glyph information.
* The `BitmapTextSize` object returned by `BitmapText.getTextBounds` has a new property called `characters` which is an array that contains the scaled position coordinates of each character in the BitmapText, which you could use for tasks such as determining which character in the BitmapText was clicked.
* `ParseXMLBitmapFont` will now calculate the WebGL uv data for the glyphs during parsing. This avoids it having to be done during rendering, saving CPU cycles on an operation that never changes.
* `ParseXMLBitmapFont` will now create a Frame object for each glyph. This means you could, for example, create a Sprite using the BitmapText texture and the glyph as the frame key, i.e.: `this.add.sprite(x, y, fontName, 'A')`.
* `BitmapTextWord`, `BitmapTextCharacter` and `BitmapTextLines` are three new type defs that are now part of the `BitmapTextSize` config object, as returned by `getTextBounds`. This improves the TypeScript defs and JS Docs for this object.
* The signature of the `ParseXMLBitmapFont` function has changed. The `frame` parameter is no longer optional, and is now the second parameter in the list, instead of being the 4th. If you call this function directly, please update your code.
* The `BitmapText.getTextBounds` method was being called every frame, even if the bounds didn't change, potentially costing a lot of CPU time depending on the text length and quantity of them. It now only updates the bounds if they change.
* The `GetBitmapTextSize` function used `Math.round` on the values, if the `round` parameter was `true`, which didn't create integers. It now uses `Math.ceil` instead to give integer results.
* The `GetBitmapTextSize` function has a new boolean parameter `updateOrigin`, which will adjust the origin of the parent BitmapText if set, based on the new bounds calculations.
* `BitmapText.preDestroy` is a new method that will tidy-up all of the BitmapText data during object destruction.
* `BitmapText.dropShadowX` is a new property that controls the horizontal offset of the drop shadow on the Bitmap Text.
* `BitmapText.dropShadowY` is a new property that controls the vertical offset of the drop shadow on the Bitmap Text.
* `BitmapText.dropShadowColor` is a new property that sets the color of the Bitmap Text drop shadow.
* `BitmapText.dropShadowAlpha` is a new property that sets the alpha of the Bitmap Text drop shadow.
* `BatchChar` is a new internal private function for batching a single character of a Bitmap Text to the pipeline.
* If you give an invalid Bitmap Font key, the Bitmap Text object will now issue a `console.warn`.
* Setting the `color` value in the `DynamicBitmapText.setDisplayCallback` would inverse the red and blue channels if the color was not properly encoded for WebGL. It is now encoded automatically, meaning you can pass normal hex values as the colors in the display callback. Fix #5225 (thanks @teebarjunk)
* If you apply `setSize` to the Dynamic BitmapText the scissor is now calculated based on the parent transforms, not just the local ones, meaning you can crop Bitmap Text objects that exist within Containers. Fix #4653 (thanks @lgibson02)
* `ParseXMLBitmapFont` has a new optional parameter `texture`. If defined, this Texture is populated with Frame data, one frame per glyph. This happens automatically when loading Bitmap Text data in Phaser.
### New Features
* `WebGLRenderer.setInt1iv` will allow you to look-up and set a 1iv uniform on the given shader.
* `Geom.Intersects.GetLineToLine` is a new function that will return a Vector3 containing the point of intersection between 2 line segments, with the `z` property holding the distance value.
* `Geom.Intersects.GetLineToPolygon` is a new function that checks for the closest point of intersection between a line segment and an array of polygons.
* `Geom.Polygon.Translate` is a new function that allows you to translate all the points of a polygon by the given values.
* `Phaser.Types.Math.Vector3Like` is a new data type representing as Vector 3 like object.
* `Phaser.Types.Math.Vector4Like` is a new data type representing as Vector 4 like object.
* `Transform.getLocalPoint` is a new method, available on all Game Objects, that takes an `x` / `y` pair and translates them into the local space of the Game Object, factoring in parent transforms and display origins.
* The `KeyboardPlugin` will now track the key code and timestamp of the previous key pressed and compare it to the current event. If they match, it will skip the event. On some systems if you were to type quickly, you would sometimes get duplicate key events firing (the exact same event firing more than once). This is now prevented from happening.
* `Display.Color.GetColorFromValue` is a new function that will take a hex color value and return it as an integer, for use in WebGL. This is now used internally by the Tint component and other classes.
* `Utils.String.RemoveAt` is a new function that will remove a character from the given index in a string and return the new string.
* `Frame.setUVs` is a new method that allows you to directly set the canvas and UV data for a frame. Use this if you need to override the values set automatically during frame creation.
### Updates and API Changes
* `Config.batchSize` has been increased from 2000 to 4096.
* Removed the Deferred Diffuse fragment and vertex shaders from the project, as they're not used.
* `StaticTilemapLayer.upload` will now set the vertex attributes and buffer the data, and handles internal checks more efficiently.
* `StaticTilemapLayer` now includes the `ModelViewProjection` mixin, so it doesn't need to modify the pipeline during rendering.
* `WebGLRenderer.textureFlush` is a new property that keeps track of the total texture flushes per frame.
* The `TextureTintStripPipeline` now extends `TextureTintPipeline` and just changes the topolgy, vastly reducing the filesize.
* `TransformMatrix.getXRound` is a new method that will return the X component, optionally passed via `Math.round`.
* `TransformMatrix.getYRound` is a new method that will return the Y component, optionally passed via `Math.round`.
* The `KeyboardPlugin` no longer emits `keydown_` events. These were replaced with `keydown-` events in v3.15. The previous event string was deprecated in v3.20.
* The `KeyboardPlugin` no longer emits `keyup_` events. These were replaced with `keyup-` events in v3.15. The previous event string was deprecated in v3.20.
* The `ScaleManager.updateBounds` method is now called every time the browser fires a 'resize' or 'orientationchange' event. This will update the offset of the canvas element Phaser is rendering to, which is responsible for keeping input positions correct. However, if you change the canvas position, or visibility, via any other method (i.e. via an Angular route) you should call the `updateBounds` method directly, yourself.
### Bug Fixes
* `RenderTexture.resize` (which is called from `setSize`) wouldn't correctly set the `TextureSource.glTexture` property, leading to `bindTexture: attempt to use a deleted object` errors under WebGL.
* The `MatterAttractors` plugin, which enables attractors between bodies, has been fixed. The original plugin only worked if the body with the attractor was _first_ in the world bodies list. It can now attract any body, no matter where in the world list it is. Fix #5160 (thanks @strahius)
* The `KeyboardManager` and `KeyboardPlugin` were both still checking for the `InputManager.useQueue` property, which was removed several versions ago.
* In Arcade Physics, Dynamic bodies would no longer hit walls when riding on horizontally moving platforms. The horizontal (and vertical) friction is now re-applied correctly in these edge-cases. Fix #5210 (thanks @Dercetech @samme)
* Calling `Rectangle.setSize()` wouldn't change the underlying geometry of the Shape Game Object, causing any stroke to be incorrectly rendered after a size change.
### Examples, Documentation and TypeScript
My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:
@samme @16patsle @scott20145
## Version 3.24.1 - Rem - 14th July 2020
* Reverted the PR that added the parent transform to a Static Tilemap Layer as it broke tilemap rendering when the camera was zoomed (thanks @kainage)
* Fixed an error with the use of the Vector2Like type in the `Math.RotateTo` function that caused a TypeScript error on compilation
## Version 3.24.0 - Rem - 13th July 2020
### Arcade Physics New Features, Updates and Fixes
* When colliding physics groups with the search tree enabled, there was an unnecessary intersection test for each body returned by the search (thanks @samme)
* When doing an overlap collision, there was an unnecessary intersection test for each pair of overlapping bodies (thanks @samme)
* Sprite vs. Static Group collision tests now always use the static tree (thanks @samme)
* Fixed a bug where if you added a static body to a sprite with scale ≠ 1, the body position was incorrect (thanks @samme)
* If you passed in an array of `children` when creating a Physics Group, they didn't receive bodies. Fix #5152 (thanks @samme)
* New types allow for better docs / TypeScript defs especially in the Factory functions: `ArcadePhysicsCallback`, `GameObjectWithBody`, `GameObjectWithDynamicBody`, `GameObjectWithStaticBody`, `ImageWithDynamicBody`, `ImageWithStaticBody`, `SpriteWithDynamicBody` and `SpriteWithStaticBody`. Fix #4994 (thanks @samme @gnesher)
* `Body.updateFromGameObject` is a new method that extracts the relevant code from `preUpdate`, allowing you to read the body's new position and center immediately, before the next physics step. It also lets `refreshBody` work for dynamic bodies, where previously it would error (thanks @samme)
* Momentum exchange wasn't working correctly vs. immovable bodies. The movable body tended to stop. Fix #4770 (thanks @samme)
* The Body mass was decreasing the inertia instead of increasing it. Fix #4770 (thanks @samme)
* The separation vector seemed to be incorrect, causing the slip / slide collisions. The separation is now correct for circlecircle collisions (although not fully for circlerectangle collisions), part fix #4770 (thanks @samme)
* The Arcade Body delta was incorrectly calculated on bodies created during the `update` step, causing the position to be off. Fix #5204 (thanks @zackexplosion @samme)
* `Arcade.Components.Size.setBodySize` is a new method available on Arcade Physics Game Objects that allows you to set the body size. This replaces `setSize` which is now deprecated. Fix #4786 (thanks @wingyplus)
### New Features
* The Animation component has a new property `nextAnimsQueue` which allows you to sequence Sprite animations to play in order, i.e: `this.mole.anims.play('digging').anims.chain('lifting').anims.chain('looking').anims.chain('lowering');` (thanks @tgroborsch)
* `Group.setActive` is a new method that will set the active state of a Group, just like it does on other Game Objects (thanks @samme)
* `Group.setName` is a new method that will set the name property of a Group, just like it does on other Game Objects (thanks @samme)
* `TWEEN_STOP` is a new event dispatched by a Tween when it stops playback (thanks @samme @RollinSafary)
* You can now specify an `onStop` callback when creating a Tween as part of the tween config, which is invoked when a Tween stops playback (thanks @samme @RollinSafary)
* Previously, if you created a timeline and passed no tweens in the config, the timeline would be created but all config properties were ignored. Now the timeline's own properties (completeDelay, loop, loopDelay, useFrames, onStart, onUpdate, onLoop, onYoyo, onComplete, etc.) are set from the config properly (thanks @samme)
* `TextStyle.wordWrapWidth` lets you set the maximum width of a line of text (thanks @mikewesthad)
* `TextStyle.wordWrapCallback` is a custom function that will is responsible for wrapping the text (thanks @mikewesthad)
* `TextStyle.wordWrapCallbackScope` is the scope that will be applied when the `wordWrapCallback` is invoked (thanks @mikewesthad)
* `TextStyle.wordWrapUseAdvanced` controls whether or not to use the advanced wrapping algorithm (thanks @mikewesthad)
* `KeyboardPlugin.removeAllKeys` is a new method that allows you to automatically remove all Key instances that the plugin has created, making house-keeping a little easier (thanks @samme)
* `Math.RotateTo` is a new function that will position a point at the given angle and distance (thanks @samme)
* `Display.Bounds.GetBounds` is a new function that will return the un-transformed bounds of the given Game Object as a Rectangle (thanks @samme)
### Updates
* The `Pointer.dragStartX/YGlobal` and `Pointer.dragX/Y` values are now populated from the `worldX/Y`, which means using those values directly in Input Drag callbacks will now work when the Camera is zoomed. Fix #4755 (thanks @braindx)
* The `browser` field has been added to the Phaser `package.json` pointing to the `dist/phaser.js` umd build (thanks @FredKSchott)
* Calling `TimeStep.wake()` while the loop is running will now cause nothing to happen, rather than sleeping and then waking again (thanks @samme)
* `Container.getBounds` will no longer set the temp rect bounds to the first child of the Container by default (which would error if the child had no bounds, like a Graphics object) and instead sets it as it iterates the children (thanks @blopa)
* `File.state` will now be set to the `FILE_LOADING` state while loading and `FILE_LOADED` after loading (thanks @samme)
* `BaseCamera.cull` now moves some of its calculations outside of the cull loop to speed it up (thanks @samme)
* `SceneManager.createSceneFromInstance` had a small refactor to avoid a pointless condition (thanks @samme)
### Bug Fixes
* Fixed a TypeError warning when importing JSON objects directly to the `url` argument of any of the Loader filetypes. Fix #5189 (thanks @awweather @samme)
* The `NOOP` function was incorrectly imported by the Mouse and Keyboard Manager. Fix #5170 (thanks @samme @gregolai)
* When Audio files failed to decode on loading, they would always show 'undefined' as the key in the error log, now they show the actual key (thanks @samme)
* When the Sprite Sheet parser results in zero frames, the warning will now tell you the texture name that caused it (thanks @samme)
* `KeyboardPlugin.checkDown` didn't set the `duration` to zero if the parameter was omitted, causing it to always return false. Fix #5146 (thanks @lozzajp)
* If you passed in an array of `children` when creating a Group, they were not added and removed correctly. Fix #5151 (thanks @samme)
* When using HTML5 Audio with `pauseOnBlur` (the default), if you play a sound, schedule stopping the sound (e.g., timer, tween complete callback), leave the page, and return to the page, the sound `stop()` will error (thanks @samme)
* Using a Render Texture when you're also using the headless renderer would cause an error (thanks @samme)
* `Ellipse.setWidth` would incorrectly set the `xRadius` to the diameter (thanks @rexrainbow)
* `Ellipse.setHeight` would incorrectly set the `yRadius` to the diameter (thanks @rexrainbow)
* When specifically setting the `parent` property in the Game Config to `null` the canvas was appended to the document body, when it should have been ignored (allowing you to add it to the dom directly). Fix #5191 (thanks @MerganThePirate)
* Containers will now apply nested masks correctly when using the Canvas Renderer specifically (thanks @scott20145)
* Calling `Scale.startFullScreen` would fail in Safari on Mac OS, throwing a `fullscreenfailed` error. It now triggers fullscreen mode correctly, as on other browsers. Fix #5143 (thanks @samme @novaknole)
* Calling `setCrop` on a Matter Physics Sprite would throw a TypeError, but will now crop correctly. Not that it only crops the texture, the body is unaffected. Fix #5211 (thanks @MatthewRorke @samme)
* The Static Tilemap Layer would ignore the layer rotation and parent transform when using WebGL (but worked in Canvas). Both modes now work in the same manner (thanks @cruzdanilo)
* Calling `getTextBounds` on a BitmapText object would return the incorrect values if the origin had been changed, but the text itself had not, as it was using out of date dimensions. Changing the origin now automatically triggers BitmapText to be dirty, forcing the bounds to be refreshed. Fix #5121 (thanks @thenonamezz)
* The ISO Triangle shape would skip rendering the left side of the first triangle in the batch. It now renders all ISO Triangles correctly. Fix #5164 (thanks @mattjennings)
### Examples, Documentation and TypeScript
My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:
@samme @SanderVanhove @SirJosh3917 @mooreInteractive @A-312 @lozzajp @mikewesthad @j-waters @futuremarc
## Version 3.23 - Ginro - 27th April 2020
### JSDocs
The following sections now have 100% complete JSDoc coverage:
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
@ -25,6 +288,13 @@ The following features are now deprecated and will be removed in a future versio
* 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
@ -33,6 +303,33 @@ The following features are now deprecated and will be removed in a future versio
* `Config.loaderWithCredentials` is the new global setting for `XHRSettings.withCredentials`.
* `Camera.renderToGame` is a new property used in conjunction with `renderToTexture`. It controls if the Camera should still render to the Game canvas after rendering to its own texture or not. By default, it will render to both, but you can now toggle this at run-time.
* `Camera.setRenderToTexture` has a new optional parameter `renderToGame` which sets the `Camera.renderToGame` property, controlling if the Camera should render to both its texture and the Game canvas, or just its texture.
* The free version of Texture Packer exports a `pivot` property when using JSON Array or Hash, however the Texture Packer Phaser export uses the `anchor` property. This update allows the loaders to work with either property, regardless of which export you use (thanks @veleek)
* `get()` is a new method in the HTML and Web Audio Sound Managers that will get the first sound in the manager matching the given key, if any (thanks @samme)
* `getAll()` is a new method in the HTML and Web Audio Sound Managers that will get all sounds in the manager matching the given key, if any (thanks @samme)
* `removeAll()` is a new method in the HTML and Web Audio Sound Managers that will remove all sounds in the manager, destroying them (thanks @samme)
* `stopByKey()` is a new method in the HTML and Web Audio Sound Managers that will stop any sound in the manager matching the given key, if any (thanks @samme)
* `Rectangle.FromXY` is a new function that will create the smallest Rectangle containing two coordinate pairs, handy for marquee style selections (thanks @samme)
* `PathFollower.pathDelta` is a new property that holds the distance the follower has traveled from the previous point to the current one, at the last update (thanks @samme)
* `Vector2.fuzzyEquals` is a new method that will check whether the Vector is approximately equal to a given Vector (thanks @samme)
* `Vector2.setAngle` is a new method that will set the angle of the Vector (thanks @samme)
* `Vector2.setLength` is a new method that will set the length, or magnitude of the Vector (thanks @samme)
* `Vector2.normalizeLeftHand` is a new method that will rotate the Vector to its perpendicular, in the negative direction (thanks @samme)
* `Vector2.limit` is a new method that will limit the length, or magnitude of the Vector (thanks @samme)
* `Vector2.reflect` is a new method that will reflect the Vector off a line defined by a normal (thanks @samme)
* `Vector2.mirror` is a new method that will reflect the Vector across another (thanks @samme)
* `Vector2.rotate` is a new method that will rotate the Vector by an angle amount (thanks @samme)
* `Math.Angle.Random` is a new function that will return a random angle in radians between -pi and pi (thanks @samme)
* `Math.Angle.RandomDegrees` is a new function that will return a random angle in degrees between -180 and 180 (thanks @samme)
* `Physics.Arcade.World.fixedStep` is a new boolean property that synchronizes the physics fps to the rendering fps when enabled. This can help in some cases where "glitches" can occur in the movement of objects. These glitches are especially noticeable on objects that move at constant speed and the fps are not consistent. Enabling this feature disables the fps and timeScale properties of the Arcade.World class (thanks @jjcapellan)
* `Curves.Path.getTangent` is a new method that gets a unit vector tangent at a relative position on the path (thanks @samme)
* `DataManager.inc` is a new method that will increase a value for the given key. If the key doesn't already exist in the Data Manager then it is increased from 0 (thanks @rexrainbow)
* `DataManager.toggle` is a new method that will toggle a boolean value for the given key. If the key doesn't already exist in the Data Manager then it is toggled from false (thanks @rexrainbow)
* The Tiled parser will now recognize Tiled `point objects` and export them with `point: true`. Equally, Sprites generated via `createFromObjects` are now just set to the position of the Point object, using the Sprites dimensions. This is a breaking change, so if you are using Point objects and `createFromObjects` please re-test your maps against this release of Phaser (thanks @samme)
* You can now use Blob URLs when loading `Audio` objects via the Loader (thanks @aucguy)
* You can now use Blob URLs when loading `Video` objects via the Loader (thanks @aucguy)
* Tiled Image Collections now have rudimentary support and will create a single tileset per image. This is useful for prototyping, but should not be used heavily in production. See #4964 (thanks @gogoprog)
* When loading files using your own XHR Settings you can now use the new property `headers` to define an object containing multiple headers, all of which will be sent with the xhr request (thanks @jorbascrumps)
* `Camera.rotateTo` is a new Camera effect that allows you to set the rotation of the camera to a given value of the duration specified (thanks @jan1za)
### Updates
@ -40,6 +337,12 @@ The following features are now deprecated and will be removed in a future versio
* `Animation.setCurrentFrame` will no longer try to call `setOrigin` or `updateDisplayOrigin` if the Game Object doesn't have the Origin component, preventing unknown function errors.
* `MatterTileBody` now extends `EventEmitter`, meaning you can listen to collision events from Tiles directly and it will no longer throw errors about `gameObject.emit` not working. Fix #4967 (thanks @reinildo)
* Added `MatterJS.BodyType` to `GameObject.body` type. Fix #4962 (thanks @meisterpeeps)
* The `JSONHash` loader didn't load custom pivot information, but `JSONArray` did. So that functionality has been duplicated into the `JSONHash` file type (thanks @veleek)
* When enabling a Game Object for input debug, the debug body's depth was 0. It's now set to be the same depth as the actual Game Object (thanks @mktcode)
* Spine Files can now be loaded via a manifest, allowing you to specify a prefix in the loader object and providing absolute paths to textures. Fix #4813 (thanks @FostUK @a610569731)
* `collideSpriteVsGroup` now exits early when the Sprite has `checkCollision.none`, skipping an unnecessary iteration of the group (thanks @samme)
* `collideSpriteVsGroup` when looping through the tree results now skips bodies with `checkCollision.none` (thanks @samme)
* When enabling a Game Object for Input Debugging the created debug shape will now factor in the position, scale and rotation of the Game Objects parent Container, if it has one (thanks @scott20145)
### Bug Fixes
@ -49,12 +352,39 @@ The following features are now deprecated and will be removed in a future versio
* The `Arcade Physics Static Body` center was incorrect after construction. Probably caused problems with circle collisions. Fix #4770 (thanks @samme)
* An Arcade Physics Body `center` and `position` are now correct after construction and before preUpdate(), for any Game Object origin or scale (thanks @samme)
* When calling `Body.setSize` with the `center` parameter as `true` the calculated offset would be incorrect for scaled Game Objects. The offset now takes scaling into consideration (thanks @samme)
* `HTML5AudioFile.load` would throw an error in strict mode (thanks @samme)
* When using the `No Audio` Sound Manager, calling `destroy()` would cause a Maximum call stack size exceeded error as it was missing 6 setter methods. It will now destroy properly (thanks @samme)
* When using HTML5 Audio, setting the game or sound volume outside of the range 0-1 would throw an index size error. The value is now clamped before being set (thanks @samme)
* Sound Managers were still listening to Game BLUR, FOCUS, and PRE_STEP events after being destroyed. These events are now cleared up properly (thanks @samme)
* In WebGL, the `TextureTintPipeline` is now set before rendering any camera effects. If the pipeline had been changed, the effects would not run (thanks @TroKEMp)
* When transitioning to a sleeping Scene, the transition `data` wasn't sent to the Scene `wake` method. It's now sent across to both sleeping and waking scenes. Fix #5078 (thanks @MrMadClown)
* `Scale.lockOrientation('portrait')` would throw a runtime error in Firefox: 'TypeError: 'mozLockOrientation' called on an object that does not implement interface Screen.' It no longer does this. Fix #5069 (thanks @123survesh)
* The `FILE_COMPLETE` event was being emitted twice for a JSON loaded animation file. It now only fires once. Fix #5059 (thanks @jjcapellan)
* If you restart or stop / start a scene and then queue at least one new file in `preload`, the scenes `update` function is called before `create`, likely causing an error. Fix #5065 (thanks @samme)
* `Circle.GetPoints` will now check that `stepRate` is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
* `Ellipse.GetPoints` will now check that `stepRate` is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
* `Line.GetPoints` will now check that `stepRate` is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
* `Polygon.GetPoints` will now check that `stepRate` is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
* `Rectangle.GetPoints` will now check that `stepRate` is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
* `Triangle.GetPoints` will now check that `stepRate` is > 0 to avoid division by zero errors leading to the quantity becoming infinity (thanks @jdcook)
* Changing the game size with a scale mode of FIT resulted in a canvas with a incorrect aspect ratio. Fix #4971 (thanks @Kitsee @samme)
* The Matter Physics `Common.isString` function would cause a 'TypeError: Invalid calling object' in Internet Explorer (thanks @samme)
* `Arcade.Body.checkCollision.none` did not prevent collisions with Tiles. Now it does (thanks @samme)
* When running in HEADLESS mode, using a `Text` Game Object would cause a runtime error "Cannot read property gl of null". Fix #4976 (thanks @raimon-segura @samme)
* The Tilemap `LayerData` class `properties` property has been changed from 'object' to an array of objects, which is what Tiled exports when defining layer properties in the editor. Fix #4983 (thanks @Nightspeller)
* `AudioFile` and `VideoFile` had their state set to `undefined` instead of `FILE_PROCESSING` (thanks @samme)
* `Container.getBounds` would return incorrect values if it had child Containers within it. Fix #4580 (thanks @Minious @thedrint)
* The Loader no longer prepends the current path to the URL if it's a Blob object (thanks @aucguy)
* Spine Atlases can now be loaded correctly via Asset Packs, as they now have the right index applied to them (thanks @jdcook)
* Input events for children inside nested Containers would incorrectly fire depending on the pointer position (thanks @rexrainbow)
* Animations with both `yoyo` and `repeatDelay` set will respect the delay after each yoyo runs (thanks @cruzdanilo)
* `CanvasTexture.setSize` forgot to update the `width` and `height` properties of the Texture itself. These now match the underlying canvas element. Fix #5054 (thanks @sebbernery)
### Examples, Documentation and TypeScript
My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:
@JasonHK @supertommy @majalon @samme
@JasonHK @supertommy @majalon @samme @MartinBlackburn @halilcakar @jcyuan @MrMadClown @Dinozor @EmilSV @Jazcash
## Version 3.22 - Kohaku - January 15th 2020

378
README.md
View file

@ -17,7 +17,7 @@ Thousands of developers from indie and multi-national digital agencies, and univ
**Learn:** [API Docs](https://photonstorm.github.io/phaser3-docs/index.html), [Support Forum][forum] and [StackOverflow](https://stackoverflow.com/questions/tagged/phaser-framework)<br />
**Code:** 1700+ [Examples](https://phaser.io/examples) (source available in this [repo][examples])<br />
**Read:** The [Phaser World](#newsletter) Newsletter<br />
**Chat:** [Discord](https://phaser.io/community/discord) and [Slack](https://phaser.io/community/slack)<br />
**Discord:** Join us on [Discord](https://phaser.io/community/discord)<br />
**Extend:** With [Phaser Plugins](https://phaser.io/shop/plugins)<br />
**Be awesome:** [Support](#support) the future of Phaser<br />
@ -27,21 +27,17 @@ Grab the source and join the fun!
<div align="center"><img src="https://phaser.io/images/github/news.jpg"></div>
> 15th January 2020
> 13th July 2020
We're excited to announce the release of Phaser 3.22, the first of many in the year 2020. The main focus of 3.22 is all the work we've done on Matter Physics integration. Matter has been supported in Phaser since the first release, yet there were lots of things we wanted to do with it to make development life easier. 3.22 brings all of these to the front, including powerful new visual debugging options such as rendering contacts, velocity, the broadphase grid, sensors, joints and more. Matter also now has 100% JSDoc and TypeScript coverage and I spent a long time rebuilding the TypeScript defs by hand, in order to make them as accurate as possible.
I'm pleased to announce the immediate availability of Phaser 3.24. This release is primarily a maintenance release, with the focus mostly on bug fixes and updates. Even so, there are over 70 updates in this version alone. From improvements to the Arcade Physics system, to new Tween events and the ability to chain multiple animations, to some important fixes. If you're currently using 3.23 then we recommend this upgrade. As usual, I'd like to send my thanks to the Phaser community for their help in both reporting issues and submitting pull requests to fix them.
As well as docs and defs there are stacks of handy new methods, including intersection tests such as `intersectPoint`, `intersectRay`, `overlap` and more. New Body level collision callbacks allow you to filter collided pairs a lot more quickly now, combined with new collision events and data type defs to give you all the information you need when resolving. There are now functions to create bodies from SVG data, JSON data or Physics Editor data directly, new Body alignment features and of course bug fixes.
So, please do spend some time digging through the [Change Log](#changelog). I assure you, it's worth while :)
It's not all about Matter Physics, though. Thanks to the community, there are new Math Distance functions such as Chebyshev, Snake and Squared Points. You can now tint particles as they're emitted, Physics Groups finally let you use your own creation and removal callbacks and plenty more besides. There are, of course, lots of bug fixes too and I've done my best to address some of the most important ones. The documentation has improved yet again and with every release the TypeScript defs get stronger and stronger. So, as usual, please do spend some time digging through the [Change Log](#changelog). I assure you, it's worth while :)
I'd like to send a massive thank-you to everyone who supports [Phaser on Patreon](https://www.patreon.com/photonstorm) (and now even GitHub Sponsors, too!) Your continued backing keeps allowing me to work on Phaser full-time and this great new releases is the very real result of that. If you've ever considered becoming a backer, now is the perfect time!
With 3.22 released I will now be taking some time to carry on with Phaser 4 development, while planning out the 3.23 release as well. Even though Phaser 4 is in build I will fully support Phaser 3 for the foreseeable future. You can follow the development progress of both versions on the Phaser Patreon.
As well as all of these updates, development has been progressing rapidly on Phaser 4. If you'd like to stay abreast of developments then I'm now publishing them to the [Phaser Patreon](https://www.patreon.com/photonstorm). Here you can find details about the latest developments and concepts behind Phaser 4.
As usual, I'd like to send a massive thank-you to everyone who supports Phaser on Patreon (and now even GitHub Sponsors, too!) Your continued backing keeps allowing me to work on Phaser full-time and this great new releases is the very real result of that. If you've ever considered becoming a backer, now is the perfect time!
If you'd like to stay abreast of developments then I publish my [Developer Logs](https://phaser.io/phaser3/devlog) in the [Phaser World](https://phaser.io/community/newsletter) newsletter. Subscribe to stay in touch and get all the latest news from the core team and the wider community.
You can also follow Phaser on [Twitter](https://twitter.com/phaser_) and chat with fellow Phaser devs in our [Discord](https://phaser.io/community/discord) and [Slack](https://phaser.io/community/slack) channels.
You can also follow Phaser on [Twitter](https://twitter.com/phaser_) and chat with fellow Phaser devs in our [Discord](https://phaser.io/community/discord).
Phaser 3 wouldn't have been possible without the fantastic support of the community and Patreon. Thank you to everyone who supports our work, who shares our belief in the future of HTML5 gaming, and Phaser's role in that.
@ -77,18 +73,11 @@ Extra special thanks to the following companies who's support makes Phaser possi
* [Mozilla](https://www.mozilla.org)
* [Texture Packer](https://www.codeandweb.com/texturepacker/tutorials/how-to-create-sprite-sheets-for-phaser3?utm_source=ad&utm_medium=banner&utm_campaign=phaser-2018-10-16)
* [Twilio](https://www.twilio.com)
* [Y8 Games](https://www.y8.com)
* [Poki](https://developers.poki.com/)
* [CrazyGames](https://www.crazygames.com)
* [Lagged](https://www.lagged.com)
![Sponsors](https://phaser.io/images/github/sponsors-2019-12.png "Awesome Sponsors")
![Phaser Newsletter](https://phaser.io/images/github/div-newsletter.png "Phaser Newsletter")
<div align="center"><img src="https://phaser.io/images/github/phaser-world.png"></div>
We publish the [Phaser World](https://phaser.io/community/newsletter) newsletter. It's packed full of the latest Phaser games, tutorials, videos, meet-ups, talks, and more. The newsletter also contains our weekly Development Progress updates which let you know about the new features we're working on.
Over 140 previous editions can be found on our [Back Issues](https://phaser.io/community/backissues) page.
![Sponsors](https://phaser.io/images/github/sponsors-2020-06.png "Our Awesome Sponsors")
![Download Phaser](https://phaser.io/images/github/div-download.png "Download Phaser")
<a name="download"></a>
@ -114,13 +103,13 @@ npm install phaser
[Phaser is on jsDelivr](https://www.jsdelivr.com/projects/phaser) which is a "super-fast CDN for developers". Include the following in your html:
```html
<script src="//cdn.jsdelivr.net/npm/phaser@3.22.0/dist/phaser.js"></script>
<script src="//cdn.jsdelivr.net/npm/phaser@3.24.0/dist/phaser.js"></script>
```
or the minified version:
```html
<script src="//cdn.jsdelivr.net/npm/phaser@3.22.0/dist/phaser.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/phaser@3.24.0/dist/phaser.min.js"></script>
```
### API Documentation
@ -170,54 +159,20 @@ Tutorials and guides on Phaser 3 development are being published every week.
* The [Complete Phaser 3 Game Development course](https://academy.zenva.com/product/html5-game-phaser-mini-degree/?a=13) contains over 15 hours of videos covering all kinds of important topics.
* Plus, there are [over 700 Phaser tutorials](http://phaser.io/learn) listed on the official website.
Also, please subscribe to the [Phaser World](https://phaser.io/community/newsletter) newsletter for details about new tutorials as they are published.
### Facebook Instant Games
Phaser 3.13 introduced the new [Facebook Instant Games](http://phaser.io/news/2018/10/facebook-instant-games-phaser-tutorial) 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.
We've 3 tutorials related to Facebook Instant Games and Phaser:
We've 3 tutorials related specifically to creating **Facebook Instant Games** with Phaser:
* [Getting Started with Facebook Instant Games](http://phaser.io/news/2018/10/facebook-instant-games-phaser-tutorial)
* [Facebook Instant Games Leaderboards Tutorial](http://phaser.io/news/2018/11/facebook-instant-games-leaderboards-tutorial)
* [Displaying Ads in your Instant Games](http://phaser.io/news/2018/12/facebook-instant-games-ads-tutorial)
A special build of Phaser with the Facebook Instant Games Plugin ready-enabled is [available on jsDelivr](https://www.jsdelivr.com/projects/phaser). Include the following in your html:
```html
<script src="//cdn.jsdelivr.net/npm/phaser@3.22.0/dist/phaser-facebook-instant-games.js"></script>
```
or the minified version:
```html
<script src="//cdn.jsdelivr.net/npm/phaser@3.22.0/dist/phaser-facebook-instant-games.min.js"></script>
```
The build files are in the git repository in the `dist` folder, and you can also include the plugin in custom builds.
### Source Code Examples
During our development of Phaser 3, we created hundreds of examples with the full source code and assets ready available. These examples are now fully integrated into the [Phaser website](https://phaser.io/examples). You can also browse them on [Phaser 3 Labs](https://labs.phaser.io) via a more advanced interface, or clone the [examples repo][examples]. We are constantly adding to and refining these examples.
### Huge list of Phaser 3 Plugins
Super community member RexRainbow has been publishing Phaser 3 content for years, building up an impressive catalogue in that time. You'll find [loads of plugins](https://rexrainbow.github.io/phaser3-rex-notes/docs/site/index.html#list-of-my-plugins), from UI controls such as text input boxes, to Firebase support, Finite State Machines and lots more. As well as the plugins there is also a comprehensive set of 'Notes' about Phaser 3, going into great detail about how the various systems work. It's an invaluable resource and well worth checking out at [https://rexrainbow.github.io](https://rexrainbow.github.io/phaser3-rex-notes/docs/site/index.html)
### Create Your First Phaser 3 Example
Create an `index.html` page locally and paste the following code into it:
@ -226,7 +181,7 @@ Create an `index.html` page locally and paste the following code into it:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/phaser@3.22.0/dist/phaser-arcade-physics.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/phaser@3.24.0/dist/phaser-arcade-physics.min.js"></script>
</head>
<body>
@ -314,7 +269,9 @@ Run it in your browser and you'll see the following:
This is a tiny example, and there are hundreds more for you to explore, but hopefully it shows how expressive and quick Phaser is to use. With just a few easily readable lines of code, we've got something pretty impressive up on screen!
Subscribe to our newsletter for further tutorials and examples.
![Ourcade](https://phaser.io/images/github/ourcade.jpg "Ourcade")
Ourcade have published [two great Phaser 3 books](https://blog.ourcade.co/). They'll take you from getting set-up, through to finishing your first game using modern JavaScript or TypeScript and they're both completely free! They also publish a huge range of quality tutorials and videos, so be sure to check out their site every week.
![Building Phaser](https://phaser.io/images/github/div-building-phaser.png "Building Phaser")
@ -337,257 +294,74 @@ You can then run `webpack` to create a development build in the `build` folder w
# Change Log
## Version 3.22 - Kohaku - January 15th 2020
## Version 3.24 - Rem - 13th July 2020
### Matter Physics
### Arcade Physics New Features, Updates and Fixes
All of the following are specific to the Matter Physics implementation used by Phaser:
#### Matter Physics New Features
* Matter Physics now has 100% JSDoc coverage! Woohoo :)
* Matter Physics now has brand new TypeScript defs included in the `types` folder :)
* `MatterDebugConfig` is a new configuration object that contains all of the following new Matter debug settings:
* `showAxes`- Render all of the body axes?
* `showAngleIndicator`- Render just a single body axis?
* `angleColor`- The color of the body angle / axes lines.
* `showBroadphase`- Render the broadphase grid?
* `broadphaseColor`- The color of the broadphase grid.
* `showBounds`- Render the bounds of the bodies in the world?
* `boundsColor`- The color of the body bounds.
* `showVelocity`- Render the velocity of the bodies in the world?
* `velocityColor`- The color of the body velocity line.
* `showCollisions`- Render the collision points and normals for colliding pairs.
* `collisionColor`- The color of the collision points.
* `showSeparation`- Render lines showing the separation between bodies.
* `separationColor`- The color of the body separation line.
* `showBody`- Render the dynamic bodies in the world to the Graphics object?
* `showStaticBody`- Render the static bodies in the world to the Graphics object?
* `showInternalEdges`- When rendering bodies, render the internal edges as well?
* `renderFill`- Render the bodies using a fill color.
* `renderLine`- Render the bodies using a line stroke.
* `fillColor`- The color value of the fill when rendering dynamic bodies.
* `fillOpacity`- The opacity of the fill when rendering dynamic bodies, a value between 0 and 1.
* `lineColor`- The color value of the line stroke when rendering dynamic bodies.
* `lineOpacity`- The opacity of the line when rendering dynamic bodies, a value between 0 and 1.
* `lineThickness`- If rendering lines, the thickness of the line.
* `staticFillColor`- The color value of the fill when rendering static bodies.
* `staticLineColor`- The color value of the line stroke when rendering static bodies.
* `showSleeping`- Render any sleeping bodies (dynamic or static) in the world to the Graphics object?
* `staticBodySleepOpacity`] - The amount to multiply the opacity of sleeping static bodies by.
* `sleepFillColor`- The color value of the fill when rendering sleeping dynamic bodies.
* `sleepLineColor`- The color value of the line stroke when rendering sleeping dynamic bodies.
* `showSensors`- Render bodies or body parts that are flagged as being a sensor?
* `sensorFillColor`- The fill color when rendering body sensors.
* `sensorLineColor`- The line color when rendering body sensors.
* `showPositions`- Render the position of non-static bodies?
* `positionSize`- The size of the rectangle drawn when rendering the body position.
* `positionColor`- The color value of the rectangle drawn when rendering the body position.
* `showJoint`- Render all world constraints to the Graphics object?
* `jointColor`- The color value of joints when `showJoint` is set.
* `jointLineOpacity`- The line opacity when rendering joints, a value between 0 and 1.
* `jointLineThickness`- The line thickness when rendering joints.
* `pinSize`- The size of the circles drawn when rendering pin constraints.
* `pinColor`- The color value of the circles drawn when rendering pin constraints.
* `springColor`- The color value of spring constraints.
* `anchorColor`- The color value of constraint anchors.
* `anchorSize`- The size of the circles drawn as the constraint anchors.
* `showConvexHulls`- When rendering polygon bodies, render the convex hull as well?
* `hullColor`- The color value of hulls when `showConvexHulls` is set.
* `World.renderBody` is a new method that will render a single Matter Body to the given Graphics object. This is used internally during debug rendering but is also public. This allows you to control which bodies are rendered and to which Graphics object, should you wish to use them in-game and not just during debugging.
* `World.renderConstraint` is a new method that will render a single Matter Constraint, such as a pin or a spring, to the given Graphics object. This is used internally during debug rendering but is also public. This allows you to control which constraints are rendered and to which Graphics object, should you wish to use them in-game and not just during debugging.
* `World.renderConvexHull` is a new method that will render the convex hull of a single Matter Body, to the given Graphics object. This is used internally during debug rendering but is also public. This allows you to control which hulls are rendered and to which Graphics object, should you wish to use them in-game and not just during debugging.
* `World.renderGrid` is a new method that will render the broadphase Grid to the given graphics instance.
* `World.renderBodyBounds` is a new method that will render the bounds of all the given bodies to the given graphics instance.
* `World.renderBodyAxes` is a new method that will render the axes of all the given bodies to the given graphics instance.
* `World.renderBodyVelocity` is a new method that will render a velocity line for all the given bodies to the given graphics instance.
* `World.renderSeparations` is a new method that will render the separations in the current pairs list to the given graphics instance.
* `World.renderCollisions` is a new method that will render the collision points and normals in the current pairs list to the given graphics instance.
* `World.getAllBodies` is a new method that will return all bodies in the Matter World.
* `World.getAllConstraints` is a new method that will return all constraints in the Matter World.
* `World.getAllComposites` is a new method that will return all composites in the Matter World.
* `MatterPhysics.composite` is a new reference to the `Matter.Composite` module for easy access from within a Scene.
* `MatterPhysics.detector` is a new reference to the `Matter.Dectector` module for easy access from within a Scene.
* `MatterPhysics.grid` is a new reference to the `Matter.Grid` module for easy access from within a Scene.
* `MatterPhysics.pair` is a new reference to the `Matter.Pair` module for easy access from within a Scene.
* `MatterPhysics.pairs` is a new reference to the `Matter.Pairs` module for easy access from within a Scene.
* `MatterPhysics.query` is a new reference to the `Matter.Query` module for easy access from within a Scene.
* `MatterPhysics.resolver` is a new reference to the `Matter.Resolver` module for easy access from within a Scene.
* `MatterPhysics.sat` is a new reference to the `Matter.SAT` module for easy access from within a Scene.
* `MatterPhysics.constraint` is a new reference to the `Matter.Constraint` module for easy access from within a Scene.
* `MatterPhysics.composites` is a new reference to the `Matter.Composites` module for easy access from within a Scene.
* `MatterPhysics.axes` is a new reference to the `Matter.Axes` module for easy access from within a Scene.
* `MatterPhysics.bounds` is a new reference to the `Matter.Bounds` module for easy access from within a Scene.
* `MatterPhysics.svg` is a new reference to the `Matter.Svg` module for easy access from within a Scene.
* `MatterPhysics.vector` is a new reference to the `Matter.Vector` module for easy access from within a Scene.
* `MatterPhysics.vertices` is a new reference to the `Matter.Vertices` module for easy access from within a Scene.
* `BEFORE_ADD` is a new Event dispatched by `Matter.World` when a Body or Constraint is about to be added to the World.
* `AFTER_ADD` is a new Event dispatched by `Matter.World` when a Body or Constraint has been added to the World.
* `BEFORE_REMOVE` is a new Event dispatched by `Matter.World` when a Body or Constraint is about to be removed from the World.
* `AFTER_REMOVE` is a new Event dispatched by `Matter.World` when a Body or Constraint has been removed from the World.
* `Body.render.lineOpacity` is a new property on the Matter Body object that allows for custom debug rendering.
* `Body.render.lineThickness` is a new property on the Matter Body object that allows for custom debug rendering.
* `Body.render.fillOpacity` is a new property on the Matter Body object that allows for custom debug rendering.
* `World.setCompositeRenderStyle` is a new method that lets you quickly set the render style values on the children of the given compposite.
* `World.setBodyRenderStyle` is a new method that lets you quickly set the render style values on the given Body.
* `World.setConstraintRenderStyle` is a new method that lets you quickly set the render style values on the given Constraint.
* You can now set `restingThresh` in the Matter Configuration file to adjust the Resolver property.
* You can now set `restingThreshTangent` in the Matter Configuration file to adjust the Resolver property.
* You can now set `positionDampen` in the Matter Configuration file to adjust the Resolver property.
* You can now set `positionWarming` in the Matter Configuration file to adjust the Resolver property.
* You can now set `frictionNormalMultiplier` in the Matter Configuration file to adjust the Resolver property.
* `MatterPhysics.containsPoint` is a new method that returns a boolean if any of the given bodies intersect with the given point.
* `MatterPhysics.intersectPoint` is a new method that checks which bodies intersect with the given point and returns them.
* `MatterPhysics.intersectRect` is a new method that checks which bodies intersect with the given rectangular area, and returns them. Optionally, it can check which bodies are outside of the area.
* `MatterPhysics.intersectRay` is a new method that checks which bodies intersect with the given ray segment and returns them. Optionally, you can set the width of the ray.
* `MatterPhysics.intersectBody` is a new method that checks which bodies intersect with the given body and returns them. If the bodies are set to not collide this can be used as an overlaps check.
* `MatterPhysics.overlap` is a new method that takes a target body and checks to see if it overlaps with any of the bodies given. If they do, optional `process` and `overlap` callbacks are invoked, passing the overlapping bodies to them, along with additional collision data.
* `MatterPhysics.setCollisionCategory` is a new method that will set the collision filter category to the value given, on all of the bodies given. This allows you to easily set the category on bodies that don't have a Phaser Matter Collision component.
* `MatterPhysics.setCollisionGroup` is a new method that will set the collision filter group to the value given, on all of the bodies given. This allows you to easily set the group on bodies that don't have a Phaser Matter Collision component.
* `MatterPhysics.setCollidesWith` is a new method that will set the collision filter mask to the value given, on all of the bodies given. This allows you to easily set the filter mask on bodies that don't have a Phaser Matter Collision component.
* `Matter.Body.centerOfMass` is a new vec2 property added to the Matter Body object that retains the center of mass coordinates when the Body is first created, or has parts added to it. These are float values, derived from the body position and bounds.
* `Matter.Body.centerOffset` is a new vec2 property added to the Matter Body object that retains the center offset coordinates when the Body is first created, or has parts added to it. These are pixel values.
* `Constraint.pointAWorld` is a new method added to Matter that returns the world-space position of `constraint.pointA`, accounting for `constraint.bodyA`.
* `Constraint.pointBWorld` is a new method added to Matter that returns the world-space position of `constraint.pointB`, accounting for `constraint.bodyB`.
* `Body.setCentre` is a new method added to Matter that allows you to set the center of mass of a Body (please note the English spelling of this function.)
* `Body.scale` is a new read-only vector that holds the most recent scale values as passed to `Body.scale`.
* `Matter.Bodies.flagCoincidentParts` is a new function that will flags all internal edges (coincident parts) on an array of body parts. This was previously part of the `fromVertices` function, but has been made external for outside use.
* `Matter.getMatterBodies` is a new function that will return an array of Matter JS Bodies from the given input array, which can be Matter Game Objects, or any class that extends them.
* `Matter.World.has` is a new method that will take a Matter Body, or Game Object, and search the world for it. If found, it will return `true`.
* Matter now has the option to use the Runner that it ships with. The Matter Runner operates in two modes: fixed and variable. In the fixed mode, the Matter Engine updates at a fixed delta value every frame (which is what Phaser has used since the first version). In variable mode, the delta will be smoothed and capped each frame to keep the simulation constant, but at the cost of determininism. You can configure the runner by setting the `runner` property in the Matter Config object, both of which are fully covered with JSDocs. As of 3.22 the runner is now used by default in variable (non-fixed) mode. If you wish to return to the previous behavior, set `runner: { isFixed: true }`.
* `Body.onCollideCallback` is a new Matter Body property that can point to a callback to invoke when the body starts colliding.
* `Body.onCollideEndCallback` is a new Matter Body property that can point to a callback to invoke when the body stops colliding.
* `Body.onCollideActiveCallback` is a new Matter Body property that can point to a callback to invoke for the duration the body is colliding.
* `Body.onCollideWith` is a new Matter Body property that holds a mapping between bodies and collision callbacks.
* `MatterGameObject.setOnCollide` is a new method available on any Matter Game Object, that sets a callback that is invoked when the body collides with another.
* `MatterGameObject.setOnCollideEnd` is a new method available on any Matter Game Object, that sets a callback that is invoked when the body stops colliding.
* `MatterGameObject.setOnCollideActive` is a new method available on any Matter Game Object, that sets a callback which is invoked for the duration of the bodies collision with another.
* `MatterGameObject.setOnCollideWith` is a new method available on any Matter Game Object, that allows you to set a callback to be invoked whenever the body collides with another specific body, or array of bodies.
* `Body.gravityScale` is a new vector property that allows you to scale the effect of world gravity on a specific Body.
* `MatterPhysics._tempVec2` is a new private internal vector used for velocity and force calculations.
* `MatterPhysics.setVelocity` is a new method that will set both the horizontal and vertical linear velocity of the given physics bodies. This can be used on all Matter bodies, not just those created via the factory.
* `MatterPhysics.setVelocityX` is a new method that will set the horizontal linear velocity of the given physics bodies. This can be used on all Matter bodies, not just those created via the factory.
* `MatterPhysics.setVelocityY` is a new method that will set the vertical linear velocity of the given physics bodies. This can be used on all Matter bodies, not just those created via the factory.
* `MatterPhysics.setAngularVelocity` is a new method that will set the angular velocity of the given physics bodies. This can be used on all Matter bodies, not just those created via the factory.
* `MatterPhysics.applyForce` is a new method that applies a force to a body, at the bodies current position, including resulting torque. This can be used on all Matter bodies, not just those created via the factory.
* `MatterPhysics.applyForceFromPosition` is a new method that applies a force to a body from the given world position, including resulting torque. If no angle is given, the current body angle is used. This can be used on all Matter bodies, not just those created via the factory.
* `MatterPhysics.fromSVG` is a new method that allows you to create a Body from the given SVG path data.
* The `Matter.Factory.velocity` method has been removed. Please now use `MatterPhysics.setVelocity` instead.
* The `Matter.Factory.angularVelocity` method has been removed. Please now use `MatterPhysics.setAngularVelocity` instead.
* The `Matter.Factory.force` method has been removed. Please now use `MatterPhysics.applyForce` instead.
* `MatterBodyConfig` is a new type def that contains all of the Body configuration properties. This is now used through-out the JSDocs to aid in code-completion.
* `MatterBodyRenderConfig` is a new type def that contains all of the Body debug rendering configuration properties. This is now used through-out the JSDocs to aid in code-completion.
* `MatterChamferConfig` is a new type def that contains all of the chamfer configuration properties. This is now used through-out the JSDocs to aid in code-completion.
* `MatterCollisionFilter` is a new type def that contains all of the collision configuration properties. This is now used through-out the JSDocs to aid in code-completion.
* `MatterConstraintConfig` is a new type def that contains all of the constraint configuration properties. This is now used through-out the JSDocs to aid in code-completion.
* `MatterConstraintRenderConfig` is a new type def that contains all of the Constraint debug rendering configuration properties. This is now used through-out the JSDocs to aid in code-completion.
* `MatterSetBodyConfig` is a new type def that contains all of the Constraint debug rendering configuration properties. This is now used through-out the JSDocs to aid in code-completion.
* `MatterPhysics.getConstraintLength` is a new method that will return the length of the given constraint, as this is something you cannot get from the constraint properties directly.
* `MatterPhysics.alignBody` is a new method that will align a Body, or Matter Game Object, against the given coordinates, using the given alignment constant. For example, this allows you to easily position a body to the `BOTTOM_LEFT`, or `TOP_CENTER`, or a coordinate. Alignment is based on the body bounds.
* `Phaser.Types.Physics.Matter.MatterBody` is a new type def that contains all of the valid Matter Body objects. This is now used through-out the JSDocs to aid in code-completion.
* `Matter.BodyBounds` is a new class that contains methods to help you extract world coordinates from various points around the bounds of a Matter Body. Because Matter bodies are positioned based on their center of mass, and not a dimension based center, you often need to get the bounds coordinates in order to properly align them in the world. You can access this new class via `this.matter.bodyBounds`.
* The method signature for `Matter.PhysicsEditorParser.parseBody` has changed. It now takes `(x, y, config, options)` and no longer has `width` and `height` parameters. Please see the updated documentation for more details if you were calling this method directly.
* `MatterPhysics.fromPhysicsEditor` is a new method that allows you to create a Matter Body based on the given PhysicsEditor shape data. Previously, you could only using PhysicsEditor data with a Matter Game Object, but now you can create a body directly using it.
* `Matter.PhysicsJSONParser` is a new parser that will create Matter bodies from JSON physics data files. Currently onto the Phaser Physics Tracer app exports in this format, but details are published in the JSDocs, so any app can do so.
* `Matter.Factory.fromJSON` is a new method that will create a body from a JSON physics data file.
* The `SetBody` Matter component can now automatically use shapes created in the Phaser Physics Tracer App in the JSON data format.
* `Matter.Components.Sleep.setToSleep` is a new method available on any Matter Game Object that will send the body to sleep, if Engine sleeping has been enabled.
* `Matter.Components.Sleep.setAwake` is a new method available on any Matter Game Object that will awake a body from sleep, if Engine sleeping has been enabled.
#### Matter Physics Updates
* The `debug` property in the Matter World Config is now a `MatterDebugConfig` option instead of a boolean. However, if a boolean is given, it will use the default debug config values.
* The following `MatterWorldConfig` options have now been removed: `debugShowBody`, `debugShowStaticBody`, `debugBodyColor`, `debugBodyFillColor`, `debugStaticBodyColor`, `debugShowJoint`, `debugJointColor`, `debugWireframes`, `debugShowInternalEdges`, `debugShowConvexHulls`, `debugConvexHullColor` and `debugShowSleeping`. These can all be set via the new `MatterDebugConfig` object instead.
* The object `World.defaults` has been removed. Defaults are now access via `World.debugDefaults`.
* `World.renderBodies` has been rewritten to cache commonly-used values and avoid a situation when a single body would be rendered twice.
* The private method `World.renderConvexHulls` has been removed as it's no longer used internally.
* The private method `World.renderWireframes` has been removed as it's no longer used internally.
* The method `World.fromPath` has been removed. This was never used internally and you can get the same results by calling `Vertices.fromPath`.
* The `World.setBounds` argument `thickness` now defaults to 64, not 128, to keep it matching the Matter World Config.
* The `Body.render.fillStyle` property that existed on the Matter Body object has been removed and replaced with `fillColor`.
* The `Body.render.strokeStyle` property that existed on the Matter Body object has been removed and replaced with `lineColor`.
* `Matter.Body.render.sprite.xOffset` and `yOffset` are no longer set to anything when a Body is created. They are left as zero, or you can override them in the Body config, in which case the value is added to the sprite origin offset during a call to `setExistingBody`.
* The `Matter.Mass.centerOfMass` component property now returns the pre-calculated Body `centerOfMass` property, which is much more accurate than the previous bounds offset value.
* `Matter.setExistingBody`, which is called interally whenever a Body is set on a Game Object, now uses the new `centerOffset` values to ensure that the texture frame is correctly centered based on the center of mass, not the Body bounds, allowing for much more accurate body to texture mapping with complex multi-part compound bodies.
* The `Matter.PhysicsEditorParser` has been updated so it no longer needs to set the render offsets, and instead uses the center of mass values.
* If the `Matter.Body` config doesn't contain a `position` property, it will now default to using `Vertices.centre(body.vertices)` as the position. In most cases, this is what you need, so it saves having to pass it in the config object.
* Bumped Matter Plugin versions to avoid console logs from Common.info and Common.warn.
* `PhysicsEditorParser.parseVertices` now uses `Bodies.flagCoincidentParts` to avoid duplicating code.
* `MatterGameObject` has a new optional boolean constructor parameter `addToWorld` which lets you control if the Body should be added to the world or not. Useful for toggling off should you be merging pre-existing bodies with Game Objects.
* The `Matter.SetBody.setExistingBody` function, which all Matter Game Objects have, has a new parameter `addToWorld` which allows you to control when the body is added to the Matter world should you not require it immediately. It will also only add the body to the world if it doesn't already exist within it, or any of its composites.
* `PointerConstraint` has been recoded so that when pressed down, it only polls the World for a body hit test during the next game update. This stops it coming out of sync with the state of the world. Use of the constraint remains the same as before.
* You can now set `gravity: false` in your Matter Config and it will reset gravity from the defaults to zero.
* The internal Matter `Composite.setModified` function will now emit a `compositeModified` event, which the Matter World listens for, if debug draw is enabled, so it can update the composite children render styles.
* `Matter.PhysicsEditorParser.parseBody` can now accept a MatterBodyConfig file as a 4th parameter. This allows you to set Body properties when the body is created, overriding whatever values may have been set in the PhysicsEditor JSON.
#### Matter Physics Bug Fixes
* Due to the rewrite of the debug rendering, it is now possible to render _just_ constraints, where-as before this was only possible if bodies were being rendered as well. Fix #4880 (thanks @roberto257)
* `Matter.PhysicsEditorParser` had a bug where it would allow fixtures with non-clockwise sorted vertices through, which would break pointer constraint interaction with these bodies. The parser now sorts the vertices properly. Fix #4261 (thanks @Sanchez3)
* When colliding physics groups with the search tree enabled, there was an unnecessary intersection test for each body returned by the search (thanks @samme)
* When doing an overlap collision, there was an unnecessary intersection test for each pair of overlapping bodies (thanks @samme)
* Sprite vs. Static Group collision tests now always use the static tree (thanks @samme)
* Fixed a bug where if you added a static body to a sprite with scale ≠ 1, the body position was incorrect (thanks @samme)
* If you passed in an array of `children` when creating a Physics Group, they didn't receive bodies. Fix #5152 (thanks @samme)
* New types allow for better docs / TypeScript defs especially in the Factory functions: `ArcadePhysicsCallback`, `GameObjectWithBody`, `GameObjectWithDynamicBody`, `GameObjectWithStaticBody`, `ImageWithDynamicBody`, `ImageWithStaticBody`, `SpriteWithDynamicBody` and `SpriteWithStaticBody`. Fix #4994 (thanks @samme @gnesher)
* `Body.updateFromGameObject` is a new method that extracts the relevant code from `preUpdate`, allowing you to read the body's new position and center immediately, before the next physics step. It also lets `refreshBody` work for dynamic bodies, where previously it would error (thanks @samme)
* Momentum exchange wasn't working correctly vs. immovable bodies. The movable body tended to stop. Fix #4770 (thanks @samme)
* The Body mass was decreasing the inertia instead of increasing it. Fix #4770 (thanks @samme)
* The separation vector seemed to be incorrect, causing the slip / slide collisions. The separation is now correct for circlecircle collisions (although not fully for circlerectangle collisions), part fix #4770 (thanks @samme)
* The Arcade Body delta was incorrectly calculated on bodies created during the `update` step, causing the position to be off. Fix #5204 (thanks @zackexplosion @samme)
* `Arcade.Components.Size.setBodySize` is a new method available on Arcade Physics Game Objects that allows you to set the body size. This replaces `setSize` which is now deprecated. Fix #4786 (thanks @wingyplus)
### New Features
* `TimeStep.smoothStep` is a new boolean property that controls if any delta smoothing takes place during the game step. Delta smoothing has been enabled in Phaser since the first version and helps avoid delta spikes and dips, especially after loss of focus. However, you can now easily toggle if this happens via this property and the corresponding `FPSConfig` property.
* `Phaser.Math.Distance.BetweenPoints` is a new function that will return the distance between two Vector2-like objects (thanks @samme)
* `Phaser.Math.Distance.BetweenPointsSquared` is a new function that will return the squared distance between two Vector2-like objects (thanks @samme)
* `Phaser.Math.Distance.Chebyshev` is a new function that will return the Chebyshev (or chessboard) distance between two Vector2-like objects (thanks @samme)
* `Phaser.Math.Distance.Snake` is a new function that will return the rectilinear distance between two Vector2-like objects (thanks @samme)
* `ParticleEmitter.setTint` is a new method that will set the tint of emitted particles for the given Emitter only (thanks @samme)
* `ParticleEmitter.remove` is a new method that will remove the Emitter from its Emitter Manager (thanks @samme)
* `ParticleEmitterManager.removeEmitter` is a new method that will remove the given emitter from the manager, if the emitter belongs to it (thanks @samme)
* `AlphaSingle` is a new Game Object Component that allows a Game Object to set its alpha values, but only as a single uniform value, not on a per-quad basis.
* `Actions.AlignTo` (in combination with the new `Display.Align.To.QuickSet` function) allows you to align an array of Game Objects so they sit next to each other, one at a time. The first item isn't moved, the second is moved to sit next to the first, and so on. You can align them using any of the alignment constants (thanks @samme)
* `Scene.Systems.getData` is a new method that will return any data that was sent to the Scene by another Scene, i.e. during a `run` or `launch` command. You can access it via `this.sys.getData()` from within your Scene.
* `Group.internalCreateCallback` is a new optional callback that is invoked whenever a child is added to a Group. This is the same as `createCallback` except it's only for use by the parent class, allowing a parent to invoke a creation callback and for you to still provide one via the Group config.
* `Group.internalRemoveCallback` is a new optional callback that is invoked whenever a child is removed from a Group. This is the same as `removeCallback` except it's only for use by the parent class, allowing a parent to invoke a callback and for you to still provide one via the Group config.
* The Animation component has a new property `nextAnimsQueue` which allows you to sequence Sprite animations to play in order, i.e: `this.mole.anims.play('digging').anims.chain('lifting').anims.chain('looking').anims.chain('lowering');` (thanks @tgroborsch)
* `Group.setActive` is a new method that will set the active state of a Group, just like it does on other Game Objects (thanks @samme)
* `Group.setName` is a new method that will set the name property of a Group, just like it does on other Game Objects (thanks @samme)
* `TWEEN_STOP` is a new event dispatched by a Tween when it stops playback (thanks @samme @RollinSafary)
* You can now specify an `onStop` callback when creating a Tween as part of the tween config, which is invoked when a Tween stops playback (thanks @samme @RollinSafary)
* Previously, if you created a timeline and passed no tweens in the config, the timeline would be created but all config properties were ignored. Now the timeline's own properties (completeDelay, loop, loopDelay, useFrames, onStart, onUpdate, onLoop, onYoyo, onComplete, etc.) are set from the config properly (thanks @samme)
* `TextStyle.wordWrapWidth` lets you set the maximum width of a line of text (thanks @mikewesthad)
* `TextStyle.wordWrapCallback` is a custom function that will is responsible for wrapping the text (thanks @mikewesthad)
* `TextStyle.wordWrapCallbackScope` is the scope that will be applied when the `wordWrapCallback` is invoked (thanks @mikewesthad)
* `TextStyle.wordWrapUseAdvanced` controls whether or not to use the advanced wrapping algorithm (thanks @mikewesthad)
* `KeyboardPlugin.removeAllKeys` is a new method that allows you to automatically remove all Key instances that the plugin has created, making house-keeping a little easier (thanks @samme)
* `Math.RotateTo` is a new function that will position a point at the given angle and distance (thanks @samme)
* `Display.Bounds.GetBounds` is a new function that will return the un-transformed bounds of the given Game Object as a Rectangle (thanks @samme)
### Updates
* `Body.deltaXFinal` is a new method on Arcade Physics Bodies that will return the final change in the horizontal position of the body, as based on all the steps that took place this frame. This property is calculated during the `postUpdate` phase, so must be listened for accordingly (thanks Bambosh)
* `Body.deltaYFinal` is a new method on Arcade Physics Bodies that will return the final change in the vertical position of the body, as based on all the steps that took place this frame. This property is calculated during the `postUpdate` phase, so must be listened for accordingly (thanks Bambosh)
* `Body._tx` is a new internal private var, holding the Arcade Physics Body combined total delta x value.
* `Body._ty` is a new internal private var, holding the Arcade Physics Body combined total delta y value.
* `LineCurve.getUtoTmapping` has been updated to return `u` directly to avoid calculations as it's identical to `t` in a Line (thanks @rexrainbow)
* `Curve.getSpacedPoints` will now take an optional array as the 3rd parameter to store the points results in (thanks @rexrainbow)
* Trying to play or resume an audio file with an incorrect key will now throw a runtime error, instead of a console warning (thanks @samme)
* The `Shape` Game Object now uses the AlphaSingle component, allowing you to uniformly set the alpha of the shape, rather than a quad alpha, which never worked for Shape objects.
* The `Container` Game Object now uses the AlphaSingle component, allowing you to uniformly set the alpha of the container, rather than a quad alpha, which never worked consistently across Container children. Fix #4916 (thanks @laineus)
* The `DOMElement` Game Object now uses the AlphaSingle component, allowing you to uniformly set the alpha of the element, rather than a quad alpha, which never worked for these objects.
* The `Graphics` Game Object now uses the AlphaSingle component, allowing you to uniformly set the alpha of the element, rather than a quad alpha, which never worked for these objects.
* `TweenData` has a new property called `previous` which holds the eased property value prior to the update.
* The `TWEEN_UPDATE` event now sends two new parameters to the handler: `current` and `previous` which contain the current and previous property values.
* During `collideSpriteVsGroup` checks it will now skip bodies that are disabled to save doing a `contains` test (thanks @samme)
* `Display.Align.In.QuickSet` now accepts `LEFT_BOTTOM` as `BOTTOM_LEFT`, `LEFT_TOP` as `TOP_LEFT`, `RIGHT_BOTTOM` as `BOTTOM_RIGHT` and `RIGHT_TOP` as `TOP_RIGHT`. Fix #4927 (thanks @zaniar)
* `PhysicsGroup` now uses the new `internalCreateCallback` and `internalRemoveCallback` to handle its body creation and destruction, allowing you to use your own `createCallback` and `removeCallback` as defined in the Group config. Fix #4420 #4657 #4822 (thanks @S4n60w3n @kendistiller @scrubperson)
* `DOMElement` has a new private method `handleSceneEvent` which will handle toggling the display setting of the element when a Scene sleeps and wakes. A DOM Element will now listen for the Scene sleep and wake events. These event listeners are removed in the `preDestroy` method.
* A `DOMElement` will now set the display mode to 'none' during its render if the Scene in which it belongs is no longer visible.
* The `Pointer.dragStartX/YGlobal` and `Pointer.dragX/Y` values are now populated from the `worldX/Y`, which means using those values directly in Input Drag callbacks will now work when the Camera is zoomed. Fix #4755 (thanks @braindx)
* The `browser` field has been added to the Phaser `package.json` pointing to the `dist/phaser.js` umd build (thanks @FredKSchott)
* Calling `TimeStep.wake()` while the loop is running will now cause nothing to happen, rather than sleeping and then waking again (thanks @samme)
* `Container.getBounds` will no longer set the temp rect bounds to the first child of the Container by default (which would error if the child had no bounds, like a Graphics object) and instead sets it as it iterates the children (thanks @blopa)
* `File.state` will now be set to the `FILE_LOADING` state while loading and `FILE_LOADED` after loading (thanks @samme)
* `BaseCamera.cull` now moves some of its calculations outside of the cull loop to speed it up (thanks @samme)
* `SceneManager.createSceneFromInstance` had a small refactor to avoid a pointless condition (thanks @samme)
### Bug Fixes
* BitmapText with a `maxWidth` set wouldn't update the text correctly if it was modified post-creation. You can now update the text and/or width independantly and it'll update correctly. Fix #4881 (thanks @oxguy3)
* Text objects will no longer add any white-space when word-wrapping if the last line is only one word long. Fix #4867 (thanks @gaamoo @rexrainbow)
* When `Game.destroy` is running, Scenes are now destroyed _before_ plugins, avoiding bugs when closing down plugins and deleting Render Textures. Fix #4849 #4876 (thanks @rexrainbow @siyuanqiao)
* The `Mesh` and `Quad` Game Objects have had the `GetBounds` component removed as it cannot operate on a Mesh as they don't have origins. Fix #4902 (thanks @samme)
* Setting `lineSpacing` in the Text Game Object style config would set the value but not apply it to the Text, leaving you to call `updateText` yourself. If set, it's now applied on instantiation. Fix #4901 (thanks @FantaZZ)
* External calls to the Fullscreen API using `element.requestFullscreen()` would be blocked by the Scale Manager. The Scale Manager will no longer call `stopFullScreen` should it be triggered outside of Phaser (thanks @AdamXA)
* The `Tilemaps.Tile.tint` property wasn't working correctly as it expected the colors in the wrong order (BGR instead of RGB). It will now expect them in the correct RGB order (thanks @Aedalus @plissken2013es)
* The `ScaleManager.destroy` method wasn't being called when the Game `DESTROY` event was dispatched, causing minor gc to build up. The destroy method will now be called properly on game destruction. Fix #4944 (thanks @sunshineuoow)
* `FacebookInstantGamesPlugin.showAd` and `showVideo` will now break out of the ad iteration search once a valid ad has been found and called. Previously, it would carry on interating if the async didn't complete quickly. Fix #4888 (thanks @east62687)
* When playing an Animation, if you were to play another, then pause it, then play another the internal `_paused` wouldn't get reset, preventing you from them pausing the animations from that point on. You can now play and pause animations at will. Fix #4835 (thanks @murteira)
* In `Actions.GridAlign` if you set `width` to -1 it would align the items vertically, instead of horizontally. It now aligns them horizontally if `width` is set, or vertically if `height` is set. Fix #4899 (thanks @BenjaVR)
* A `PathFollower` with a very short duration would often not end in the correct place, which is the very end of the Path, due to the tween handling the movement not running one final update when the tween was complete. It will now always end at the final point of the path, no matter how short the duration. Fix #4950 (thanks @bramp)
* A `DOMElement` would still remain visible even if the Scene in which it belongs to was sent to sleep. A sleeping Scene shouldn't render anything. DOM Elements will now respond to sleep and wake events from their parent Scene. Fix #4870 (thanks @peonmodel)
* If a config object was passed to `MultiAtlasFile` it expected the atlas URL to be in the `url` property, however the docs and file config expected it in `atlasURL`. You can now use either of these properties to declare the url. Fix #4815 (thanks @xense)
* Fixed a TypeError warning when importing JSON objects directly to the `url` argument of any of the Loader filetypes. Fix #5189 (thanks @awweather @samme)
* The `NOOP` function was incorrectly imported by the Mouse and Keyboard Manager. Fix #5170 (thanks @samme @gregolai)
* When Audio files failed to decode on loading, they would always show 'undefined' as the key in the error log, now they show the actual key (thanks @samme)
* When the Sprite Sheet parser results in zero frames, the warning will now tell you the texture name that caused it (thanks @samme)
* `KeyboardPlugin.checkDown` didn't set the `duration` to zero if the parameter was omitted, causing it to always return false. Fix #5146 (thanks @lozzajp)
* If you passed in an array of `children` when creating a Group, they were not added and removed correctly. Fix #5151 (thanks @samme)
* When using HTML5 Audio with `pauseOnBlur` (the default), if you play a sound, schedule stopping the sound (e.g., timer, tween complete callback), leave the page, and return to the page, the sound `stop()` will error (thanks @samme)
* Using a Render Texture when you're also using the headless renderer would cause an error (thanks @samme)
* `Ellipse.setWidth` would incorrectly set the `xRadius` to the diameter (thanks @rexrainbow)
* `Ellipse.setHeight` would incorrectly set the `yRadius` to the diameter (thanks @rexrainbow)
* When specifically setting the `parent` property in the Game Config to `null` the canvas was appended to the document body, when it should have been ignored (allowing you to add it to the dom directly). Fix #5191 (thanks @MerganThePirate)
* Containers will now apply nested masks correctly when using the Canvas Renderer specifically (thanks @scott20145)
* Calling `Scale.startFullScreen` would fail in Safari on Mac OS, throwing a `fullscreenfailed` error. It now triggers fullscreen mode correctly, as on other browsers. Fix #5143 (thanks @samme @novaknole)
* Calling `setCrop` on a Matter Physics Sprite would throw a TypeError, but will now crop correctly. Not that it only crops the texture, the body is unaffected. Fix #5211 (thanks @MatthewRorke @samme)
* The Static Tilemap Layer would ignore the layer rotation and parent transform when using WebGL (but worked in Canvas). Both modes now work in the same manner (thanks @cruzdanilo)
* Calling `getTextBounds` on a BitmapText object would return the incorrect values if the origin had been changed, but the text itself had not, as it was using out of date dimensions. Changing the origin now automatically triggers BitmapText to be dirty, forcing the bounds to be refreshed. Fix #5121 (thanks @thenonamezz)
* The ISO Triangle shape would skip rendering the left side of the first triangle in the batch. It now renders all ISO Triangles correctly. Fix #5164 (thanks @mattjennings)
### Examples, Documentation and TypeScript
My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:
@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
@samme @SanderVanhove @SirJosh3917 @mooreInteractive @A-312 @lozzajp @mikewesthad @j-waters @futuremarc
Please see the complete [Change Log](https://github.com/photonstorm/phaser/blob/master/CHANGELOG.md) for previous releases.
@ -612,14 +386,14 @@ Phaser is a [Photon Storm](http://www.photonstorm.com) production.
Created by [Richard Davey](mailto:rich@photonstorm.com). Powered by coffee, anime, pixels and love.
The Phaser logo and characters are &copy; 2019 Photon Storm Limited.
The Phaser logo and characters are &copy; 2020 Photon Storm Limited.
All rights reserved.
"Above all, video games are meant to be just one thing: fun. Fun for everyone." - Satoru Iwata
[get-js]: https://github.com/photonstorm/phaser/releases/download/v3.22.0/phaser.js
[get-minjs]: https://github.com/photonstorm/phaser/releases/download/v3.22.0/phaser.min.js
[get-js]: https://github.com/photonstorm/phaser/releases/download/v3.24.0/phaser.js
[get-minjs]: https://github.com/photonstorm/phaser/releases/download/v3.24.0/phaser.min.js
[clone-http]: https://github.com/photonstorm/phaser.git
[clone-ssh]: git@github.com:photonstorm/phaser.git
[clone-ghwin]: github-windows://openRepo/https://github.com/photonstorm/phaser

View file

@ -2,10 +2,7 @@
const webpack = require('webpack');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const basePath = __dirname;
const targetFolder = 'dist';
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: 'production',
@ -57,8 +54,6 @@ module.exports = {
"typeof FEATURE_SOUND": JSON.stringify(true)
}),
new CleanWebpackPlugin([targetFolder], {
root: basePath + '/../'
})
new CleanWebpackPlugin()
]
};

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

37467
dist/phaser.js vendored

File diff suppressed because it is too large Load diff

2
dist/phaser.min.js vendored

File diff suppressed because one or more lines are too long

4544
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
{
"name": "phaser",
"version": "3.23.0-beta1",
"release": "Ginro",
"version": "3.50.0-beta.1",
"release": "Subaru",
"description": "A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.",
"author": "Richard Davey <rich@photonstorm.com> (http://www.photonstorm.com)",
"homepage": "http://phaser.io",
@ -10,6 +10,7 @@
"licenseUrl": "http://www.opensource.org/licenses/mit-license.php",
"main": "./src/phaser.js",
"types": "./types/phaser.d.ts",
"browser": "./dist/phaser.js",
"repository": {
"type": "git",
"url": "https://photonstorm@github.com/photonstorm/phaser.git"
@ -41,10 +42,9 @@
"lintfix": "eslint --config .eslintrc.json \"src/**/*.js\" --fix",
"sloc": "node-sloc \"./src\" --include-extensions \"js\"",
"bundleshaders": "node scripts/bundle-shaders.js",
"postinstall": "node scripts/support.js",
"build-tsgen": "cd scripts/tsgen && tsc",
"tsgen": "cd scripts/tsgen && jsdoc -c jsdoc-tsd.conf.json",
"test-ts": "cd scripts/tsgen/test && tsc > output.txt",
"test-ts": "cd scripts/tsgen/test && tsc --build tsconfig.json > output.txt",
"ts": "npm run tsgen && npm run test-ts",
"tsdev": "npm run build-tsgen && npm run tsgen && npm run test-ts"
},
@ -61,25 +61,25 @@
"web audio"
],
"devDependencies": {
"clean-webpack-plugin": "^0.1.19",
"dts-dom": "^3.3.0",
"eslint": "^4.19.1",
"eslint-plugin-es5": "^1.3.1",
"fs-extra": "^6.0.1",
"jsdoc": "^3.6.3",
"node-sloc": "^0.1.11",
"remove-files-webpack-plugin": "^1.1.3",
"typescript": "^3.4.5",
"uglifyjs-webpack-plugin": "^1.3.0",
"clean-webpack-plugin": "^3.0.0",
"dts-dom": "^3.6.0",
"eslint": "^7.4.0",
"eslint-plugin-es5": "^1.5.0",
"fs-extra": "^9.0.1",
"jsdoc": "^3.6.4",
"node-sloc": "^0.1.12",
"remove-files-webpack-plugin": "^1.4.3",
"typescript": "^3.9.6",
"uglifyjs-webpack-plugin": "^2.2.0",
"vivid-cli": "^1.1.2",
"webpack": "^4.23.0",
"webpack-cli": "^3.1.1",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12",
"webpack-shell-plugin": "^0.5.0"
},
"dependencies": {
"eventemitter3": "^3.1.0",
"exports-loader": "^0.7.0",
"imports-loader": "^0.8.0",
"eventemitter3": "^4.0.4",
"exports-loader": "^1.1.0",
"imports-loader": "^1.1.0",
"path": "^0.12.7"
}
}

View file

@ -16,13 +16,11 @@ var TextFile = require('../../../src/loader/filetypes/TextFile.js');
* @typedef {object} Phaser.Loader.FileTypes.SpineFileConfig
*
* @property {string} key - The key of the file. Must be unique within both the Loader and the Texture Manager.
* @property {string} [textureURL] - The absolute or relative URL to load the texture image file from.
* @property {string} [textureExtension='png'] - The default file extension to use for the image texture if no url is provided.
* @property {XHRSettingsObject} [textureXhrSettings] - Extra XHR Settings specifically for the texture image file.
* @property {string} [normalMap] - The filename of an associated normal map. It uses the same path and url to load as the texture image.
* @property {string} [atlasURL] - The absolute or relative URL to load the atlas data file from.
* @property {string} [atlasExtension='txt'] - The default file extension to use for the atlas data if no url is provided.
* @property {XHRSettingsObject} [atlasXhrSettings] - Extra XHR Settings specifically for the atlas data file.
* @property {string|string[]} [jsonURL] - The absolute or relative URL to load the JSON file from. If undefined or `null` it will be set to `<key>.json`, i.e. if `key` was "alien" then the URL will be "alien.json".
* @property {string} [atlasURL] - The absolute or relative URL to load the texture atlas data file from. If undefined or `null` it will be set to `<key>.txt`, i.e. if `key` was "alien" then the URL will be "alien.txt".
* @property {boolean} [preMultipliedAlpha=false] - Do the textures contain pre-multiplied alpha or not?
* @property {XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings.
* @property {XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas data file. Used in replacement of the Loaders default XHR Settings.
*/
/**
@ -30,7 +28,7 @@ var TextFile = require('../../../src/loader/filetypes/TextFile.js');
* A Spine File suitable for loading by the Loader.
*
* These are created when you use the Phaser.Loader.LoaderPlugin#spine method and are not typically created directly.
*
*
* For documentation about what all the arguments and configuration options mean please see Phaser.Loader.LoaderPlugin#spine.
*
* @class SpineFile
@ -86,7 +84,7 @@ var SpineFile = new Class({
for (i = 0; i < atlasURL.length; i++)
{
atlas = new TextFile(loader, {
key: key,
key: key + '_' + i,
url: atlasURL[i],
extension: GetFastValue(config, 'atlasExtension', 'atlas'),
xhrSettings: GetFastValue(config, 'atlasXhrSettings')
@ -166,7 +164,7 @@ var SpineFile = new Class({
var currentPrefix = loader.prefix;
var baseURL = GetFastValue(config, 'baseURL', this.baseURL);
var path = GetFastValue(config, 'path', this.path);
var path = GetFastValue(config, 'path', file.src.match(/^.*\//))[0];
var prefix = GetFastValue(config, 'prefix', this.prefix);
var textureXhrSettings = GetFastValue(config, 'textureXhrSettings');
@ -178,7 +176,7 @@ var SpineFile = new Class({
{
var textureURL = textures[i];
var key = 'SP' + this.multiKeyIndex + '_' + textureURL;
var key = this.prefix + textureURL;
var image = new ImageFile(loader, key, textureURL, textureXhrSettings);
@ -220,7 +218,7 @@ var SpineFile = new Class({
if (file.type === 'text')
{
atlasKey = file.key.substr(0, file.key.length - 2);
atlasKey = file.key.replace(/_[\d]$/, "");
atlasCache = file.cache;
@ -231,14 +229,14 @@ var SpineFile = new Class({
var src = file.key.trim();
var pos = src.indexOf('_');
var key = src.substr(pos + 1);
this.loader.textureManager.addImage(key, file.data);
}
file.pendingDestroy();
}
atlasCache.add(atlasKey, { preMultipliedAlpha: preMultipliedAlpha, data: combinedAtlasData });
atlasCache.add(atlasKey, { preMultipliedAlpha: preMultipliedAlpha, data: combinedAtlasData, prefix: this.prefix });
this.complete = true;
}

View file

@ -16,24 +16,24 @@ var SpineGameObject = require('./gameobject/SpineGameObject');
/**
* @classdesc
* The Spine Plugin is a Scene based plugin that handles the creation and rendering of Spine Game Objects.
*
*
* All rendering and object creation is handled via the official Spine Runtimes. This version of the plugin
* uses the Spine 3.8.72 runtimes. Please note that due to the way the Spine runtimes use semver, you will
* get breaking changes in point-releases. Therefore, files created in a different version of Spine may not
* work as a result, without you first updating the runtimes and rebuilding the plugin.
*
*
* You can find more details about Spine at http://esotericsoftware.com/.
*
*
* Please note that you require a Spine license in order to use Spine Runtimes in your games.
*
*
* You can install this plugin into your Phaser game by either importing it, if you're using ES6:
*
*
* ```javascript
* import * as SpinePlugin from './SpinePlugin.js';
* ```
*
*
* and then adding it to your Phaser Game configuration:
*
*
* ```javascript
* plugins: {
* scene: [
@ -41,10 +41,10 @@ var SpineGameObject = require('./gameobject/SpineGameObject');
* ]
* }
* ```
*
*
* If you're using ES5 then you can load the Spine Plugin in a Scene files payload, _within_ your
* Game Configuration object, like this:
*
*
* ```javascript
* scene: {
* preload: preload,
@ -56,42 +56,42 @@ var SpineGameObject = require('./gameobject/SpineGameObject');
* }
* }
* ```
*
*
* Loading it like this allows you to then use commands such as `this.load.spine` from within the
* same Scene. Alternatively, you can use the method `this.load.plugin` to load the plugin via the normal
* Phaser Loader. However, doing so will not add it to the current Scene. It will be available from any
* subsequent Scenes.
*
*
* Assuming a default environment you access it from within a Scene by using the `this.spine` reference.
*
*
* When this plugin is installed into a Scene it will add a Loader File Type, allowing you to load
* Spine files directly, i.e.:
*
*
* ```javascript
* this.load.spine('stretchyman', 'stretchyman-pro.json', [ 'stretchyman-pma.atlas' ], true);
* ```
*
*
* It also installs a Game Object Factory method, allowing you to create Spine Game Objects:
*
*
* ```javascript
* this.add.spine(512, 650, 'stretchyman')
* ```
*
*
* The first argument is the key which you used when importing the Spine data. There are lots of
* things you can specify, such as the animation name, skeleton, slot attachments and more. Please
* see the respective documentation and examples for further details.
*
*
* Phaser expects the Spine data to be exported from the Spine application in a JSON format, not binary.
* The associated atlas files are scanned for any texture files present in them, which are then loaded.
* If you have exported your Spine data with preMultipliedAlpha set, then you should enable this in the
* load arguments, or you may see black outlines around skeleton textures.
*
*
* The Spine plugin is local to the Scene in which it is installed. This means a change to something,
* such as the Skeleton Debug Renderer, in this Scene, will not impact the renderer in any other Scene.
* The only exception to this is with the caches this plugin creates. Spine atlas and texture data are
* stored in their own caches, which are global, meaning they're accessible from any Scene in your
* game, regardless if the Scene loaded the Spine data or not.
*
*
* For details about the Spine Runtime API see http://esotericsoftware.com/spine-api-reference
*
* @class SpinePlugin
@ -126,7 +126,7 @@ var SpinePlugin = new Class({
/**
* A custom cache that stores the Spine atlas data.
*
*
* This cache is global across your game, allowing you to access Spine data loaded from other Scenes,
* no matter which Scene you are in.
*
@ -138,7 +138,7 @@ var SpinePlugin = new Class({
/**
* A custom cache that stores the Spine Textures.
*
*
* This cache is global across your game, allowing you to access Spine data loaded from other Scenes,
* no matter which Scene you are in.
*
@ -178,7 +178,7 @@ var SpinePlugin = new Class({
/**
* The underlying WebGL context of the Phaser renderer.
*
*
* Only set if running in WebGL mode.
*
* @name SpinePlugin#gl
@ -198,7 +198,7 @@ var SpinePlugin = new Class({
/**
* An instance of the Spine WebGL Scene Renderer.
*
*
* Only set if running in WebGL mode.
*
* @name SpinePlugin#sceneRenderer
@ -218,7 +218,7 @@ var SpinePlugin = new Class({
/**
* An instance of the Spine Skeleton Debug Renderer.
*
*
* Only set if running in WebGL mode.
*
* @name SpinePlugin#skeletonDebugRenderer
@ -280,46 +280,46 @@ var SpinePlugin = new Class({
var add = function (x, y, key, animationName, loop)
{
var spineGO = new SpineGameObject(this.scene, _this, x, y, key, animationName, loop);
this.displayList.add(spineGO);
this.updateList.add(spineGO);
return spineGO;
};
var make = function (config, addToScene)
{
if (config === undefined) { config = {}; }
var key = GetValue(config, 'key', null);
var animationName = GetValue(config, 'animationName', null);
var loop = GetValue(config, 'loop', false);
var spineGO = new SpineGameObject(this.scene, _this, 0, 0, key, animationName, loop);
if (addToScene !== undefined)
{
config.add = addToScene;
}
BuildGameObject(this.scene, spineGO, config);
// Spine specific
var skinName = GetValue(config, 'skinName', false);
if (skinName)
{
spineGO.setSkinByName(skinName);
}
var slotName = GetValue(config, 'slotName', false);
var attachmentName = GetValue(config, 'attachmentName', null);
if (slotName)
{
spineGO.setAttachment(slotName, attachmentName);
}
return spineGO.refresh();
};
@ -411,9 +411,9 @@ var SpinePlugin = new Class({
*
* @method SpinePlugin#getAtlasCanvas
* @since 3.19.0
*
*
* @param {string} key - The key of the Spine Atlas to create.
*
*
* @return {spine.TextureAtlas} The Spine Texture Atlas, or undefined if the given key wasn't found.
*/
getAtlasCanvas: function (key)
@ -439,7 +439,7 @@ var SpinePlugin = new Class({
atlas = new Spine.TextureAtlas(atlasEntry.data, function (path)
{
return new Spine.canvas.CanvasTexture(textures.get(path).getSourceImage());
return new Spine.canvas.CanvasTexture(textures.get(atlasEntry.prefix + path).getSourceImage());
});
}
@ -452,9 +452,9 @@ var SpinePlugin = new Class({
*
* @method SpinePlugin#getAtlasWebGL
* @since 3.19.0
*
*
* @param {string} key - The key of the Spine Atlas to create.
*
*
* @return {spine.TextureAtlas} The Spine Texture Atlas, or undefined if the given key wasn't found.
*/
getAtlasWebGL: function (key)
@ -484,7 +484,7 @@ var SpinePlugin = new Class({
atlas = new Spine.TextureAtlas(atlasEntry.data, function (path)
{
return new Spine.webgl.GLTexture(gl, textures.get(path).getSourceImage(), false);
return new Spine.webgl.GLTexture(gl, textures.get(atlasEntry.prefix + path).getSourceImage(), false);
});
}
@ -495,7 +495,7 @@ var SpinePlugin = new Class({
* Adds a Spine Skeleton and Atlas file, or array of files, to the current load queue.
*
* You can call this method from within your Scene's `preload`, along with any other files you wish to load:
*
*
* ```javascript
* function preload ()
* {
@ -510,21 +510,21 @@ var SpinePlugin = new Class({
* The typical flow for a Phaser Scene is that you load assets in the Scene's `preload` method and then when the
* Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
* loaded.
*
*
* If you call this from outside of `preload` then you are responsible for starting the Loader afterwards and monitoring
* its events to know when it's safe to use the asset. Please see the Phaser.Loader.LoaderPlugin class for more details.
*
*
* Phaser expects the Spine data to be exported from the Spine application in a JSON format, not binary. The associated
* atlas files are scanned for any texture files present in them, which are then loaded. If you have exported
* your Spine data with preMultipliedAlpha set, then you should enable this in the arguments, or you may see black
* outlines around skeleton textures.
*
*
* The key must be a unique String. It is used to add the file to the global Spine cache upon a successful load.
* The key should be unique both in terms of files being loaded and files already present in the Spine cache.
* Loading a file using a key that is already taken will result in a warning.
*
* Instead of passing arguments you can pass a configuration object, such as:
*
*
* ```javascript
* this.load.spine({
* key: 'mainmenu',
@ -533,9 +533,9 @@ var SpinePlugin = new Class({
* preMultipliedAlpha: true
* });
* ```
*
*
* If you need to load multiple Spine atlas files, provide them as an array:
*
*
* ```javascript
* function preload ()
* {
@ -558,7 +558,7 @@ var SpinePlugin = new Class({
* Note: The ability to load this type of file will only be available if the Spine Plugin has been built or loaded into Phaser.
*
* @method Phaser.Loader.LoaderPlugin#spine
* @fires Phaser.Loader.LoaderPlugin#addFileEvent
* @fires Phaser.Loader.LoaderPlugin#ADD
* @since 3.19.0
*
* @param {(string|Phaser.Types.Loader.FileTypes.JSONFileConfig|Phaser.Types.Loader.FileTypes.JSONFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
@ -573,13 +573,13 @@ var SpinePlugin = new Class({
spineFileCallback: function (key, jsonURL, atlasURL, preMultipliedAlpha, jsonXhrSettings, atlasXhrSettings)
{
var multifile;
if (Array.isArray(key))
{
for (var i = 0; i < key.length; i++)
{
multifile = new SpineFile(this, key[i]);
this.addFile(multifile.files);
}
}
@ -589,23 +589,23 @@ var SpinePlugin = new Class({
this.addFile(multifile.files);
}
return this;
},
/**
* Converts the given x and y screen coordinates into the world space of the given Skeleton.
*
*
* Only works in WebGL.
*
* @method SpinePlugin#worldToLocal
* @since 3.19.0
*
*
* @param {number} x - The screen space x coordinate to convert.
* @param {number} y - The screen space y coordinate to convert.
* @param {spine.Skeleton} skeleton - The Spine Skeleton to convert into.
* @param {spine.Bone} [bone] - Optional bone of the Skeleton to convert into.
*
*
* @return {spine.Vector2} A Vector2 containing the translated point.
*/
worldToLocal: function (x, y, skeleton, bone)
@ -642,10 +642,10 @@ var SpinePlugin = new Class({
*
* @method SpinePlugin#getVector2
* @since 3.19.0
*
*
* @param {number} x - The Vector x value.
* @param {number} y - The Vector y value.
*
*
* @return {spine.Vector2} A Spine Vector2 based on the given values.
*/
getVector2: function (x, y)
@ -655,16 +655,16 @@ var SpinePlugin = new Class({
/**
* Returns a Spine Vector2 based on the given x, y and z values.
*
*
* Only works in WebGL.
*
* @method SpinePlugin#getVector3
* @since 3.19.0
*
*
* @param {number} x - The Vector x value.
* @param {number} y - The Vector y value.
* @param {number} z - The Vector z value.
*
*
* @return {spine.Vector2} A Spine Vector2 based on the given values.
*/
getVector3: function (x, y, z)
@ -674,14 +674,14 @@ var SpinePlugin = new Class({
/**
* Sets `drawBones` in the Spine Skeleton Debug Renderer.
*
*
* Only works in WebGL.
*
* @method SpinePlugin#setDebugBones
* @since 3.19.0
*
*
* @param {boolean} [value=true] - The value to set in the debug property.
*
*
* @return {this} This Spine Plugin.
*/
setDebugBones: function (value)
@ -695,14 +695,14 @@ var SpinePlugin = new Class({
/**
* Sets `drawRegionAttachments` in the Spine Skeleton Debug Renderer.
*
*
* Only works in WebGL.
*
* @method SpinePlugin#setDebugRegionAttachments
* @since 3.19.0
*
*
* @param {boolean} [value=true] - The value to set in the debug property.
*
*
* @return {this} This Spine Plugin.
*/
setDebugRegionAttachments: function (value)
@ -716,14 +716,14 @@ var SpinePlugin = new Class({
/**
* Sets `drawBoundingBoxes` in the Spine Skeleton Debug Renderer.
*
*
* Only works in WebGL.
*
* @method SpinePlugin#setDebugBoundingBoxes
* @since 3.19.0
*
*
* @param {boolean} [value=true] - The value to set in the debug property.
*
*
* @return {this} This Spine Plugin.
*/
setDebugBoundingBoxes: function (value)
@ -737,14 +737,14 @@ var SpinePlugin = new Class({
/**
* Sets `drawMeshHull` in the Spine Skeleton Debug Renderer.
*
*
* Only works in WebGL.
*
* @method SpinePlugin#setDebugMeshHull
* @since 3.19.0
*
*
* @param {boolean} [value=true] - The value to set in the debug property.
*
*
* @return {this} This Spine Plugin.
*/
setDebugMeshHull: function (value)
@ -758,14 +758,14 @@ var SpinePlugin = new Class({
/**
* Sets `drawMeshTriangles` in the Spine Skeleton Debug Renderer.
*
*
* Only works in WebGL.
*
* @method SpinePlugin#setDebugMeshTriangles
* @since 3.19.0
*
*
* @param {boolean} [value=true] - The value to set in the debug property.
*
*
* @return {this} This Spine Plugin.
*/
setDebugMeshTriangles: function (value)
@ -779,14 +779,14 @@ var SpinePlugin = new Class({
/**
* Sets `drawPaths` in the Spine Skeleton Debug Renderer.
*
*
* Only works in WebGL.
*
* @method SpinePlugin#setDebugPaths
* @since 3.19.0
*
*
* @param {boolean} [value=true] - The value to set in the debug property.
*
*
* @return {this} This Spine Plugin.
*/
setDebugPaths: function (value)
@ -800,14 +800,14 @@ var SpinePlugin = new Class({
/**
* Sets `drawSkeletonXY` in the Spine Skeleton Debug Renderer.
*
*
* Only works in WebGL.
*
* @method SpinePlugin#setDebugSkeletonXY
* @since 3.19.0
*
*
* @param {boolean} [value=true] - The value to set in the debug property.
*
*
* @return {this} This Spine Plugin.
*/
setDebugSkeletonXY: function (value)
@ -821,14 +821,14 @@ var SpinePlugin = new Class({
/**
* Sets `drawClipping` in the Spine Skeleton Debug Renderer.
*
*
* Only works in WebGL.
*
* @method SpinePlugin#setDebugClipping
* @since 3.19.0
*
*
* @param {boolean} [value=true] - The value to set in the debug property.
*
*
* @return {this} This Spine Plugin.
*/
setDebugClipping: function (value)
@ -842,14 +842,14 @@ var SpinePlugin = new Class({
/**
* Sets the given vertex effect on the Spine Skeleton Renderer.
*
*
* Only works in WebGL.
*
* @method SpinePlugin#setEffect
* @since 3.19.0
*
*
* @param {spine.VertexEffect} [effect] - The vertex effect to set on the Skeleton Renderer.
*
*
* @return {this} This Spine Plugin.
*/
setEffect: function (effect)
@ -861,15 +861,15 @@ var SpinePlugin = new Class({
/**
* Creates a Spine Skeleton based on the given key and optional Skeleton JSON data.
*
*
* The Skeleton data should have already been loaded before calling this method.
*
* @method SpinePlugin#createSkeleton
* @since 3.19.0
*
*
* @param {string} key - The key of the Spine skeleton data, as loaded by the plugin. If the Spine JSON contains multiple skeletons, reference them with a period, i.e. `set.spineBoy`.
* @param {object} [skeletonJSON] - Optional Skeleton JSON data to use, instead of getting it from the cache.
*
*
* @return {(any|null)} This Spine Skeleton data object, or `null` if the key was invalid.
*/
createSkeleton: function (key, skeletonJSON)
@ -902,7 +902,7 @@ var SpinePlugin = new Class({
var preMultipliedAlpha = atlasData.preMultipliedAlpha;
var atlasLoader = new Spine.AtlasAttachmentLoader(atlas);
var skeletonJson = new Spine.SkeletonJson(atlasLoader);
var data;
@ -923,7 +923,7 @@ var SpinePlugin = new Class({
var skeletonData = skeletonJson.readSkeletonData(data);
var skeleton = new Spine.Skeleton(skeletonData);
return { skeletonData: skeletonData, skeleton: skeleton, preMultipliedAlpha: preMultipliedAlpha };
}
else
@ -934,14 +934,14 @@ var SpinePlugin = new Class({
/**
* Creates a new Animation State and Animation State Data for the given skeleton.
*
*
* The returned object contains two properties: `state` and `stateData` respectively.
*
* @method SpinePlugin#createAnimationState
* @since 3.19.0
*
*
* @param {spine.Skeleton} skeleton - The Skeleton to create the Animation State for.
*
*
* @return {any} An object containing the Animation State and Animation State Data instances.
*/
createAnimationState: function (skeleton)
@ -955,17 +955,17 @@ var SpinePlugin = new Class({
/**
* Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
*
*
* The returned object contains two properties: `offset` and `size`:
*
*
* `offset` - The distance from the skeleton origin to the bottom left corner of the AABB.
* `size` - The width and height of the AABB.
*
* @method SpinePlugin#getBounds
* @since 3.19.0
*
*
* @param {spine.Skeleton} skeleton - The Skeleton to get the bounds from.
*
*
* @return {any} The bounds object.
*/
getBounds: function (skeleton)
@ -980,7 +980,7 @@ var SpinePlugin = new Class({
/**
* Internal handler for when the renderer resizes.
*
*
* Only called if running in WebGL.
*
* @method SpinePlugin#onResize
@ -996,14 +996,14 @@ var SpinePlugin = new Class({
sceneRenderer.camera.position.x = viewportWidth / 2;
sceneRenderer.camera.position.y = viewportHeight / 2;
sceneRenderer.camera.viewportWidth = viewportWidth;
sceneRenderer.camera.viewportHeight = viewportHeight;
},
/**
* The Scene that owns this plugin is shutting down.
*
*
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method SpinePlugin#shutdown
@ -1024,7 +1024,7 @@ var SpinePlugin = new Class({
/**
* The Scene that owns this plugin is being destroyed.
*
*
* We need to shutdown and then kill off all external references.
*
* @method SpinePlugin#destroy
@ -1060,30 +1060,30 @@ var SpinePlugin = new Class({
/**
* Creates a new Spine Game Object and adds it to the Scene.
*
*
* The x and y coordinate given is used to set the placement of the root Spine bone, which can vary from
* skeleton to skeleton. All rotation and scaling happens from the root bone placement. Spine Game Objects
* do not have a Phaser origin.
*
*
* If the Spine JSON file exported multiple Skeletons within it, then you can specify them by using a period
* character in the key. For example, if you loaded a Spine JSON using the key `monsters` and it contains
* multiple Skeletons, including one called `goblin` then you would use the key `monsters.goblin` to reference
* that.
*
*
* ```javascript
* let jelly = this.add.spine(512, 550, 'jelly', 'jelly-think', true);
* ```
*
*
* The key is optional. If not passed here, you need to call `SpineGameObject.setSkeleton()` to use it.
*
*
* The animation name is also optional and can be set later via `SpineGameObject.setAnimation`.
*
*
* Should you wish for more control over the object creation, such as setting a slot attachment or skin
* name, then use `SpinePlugin.make` instead.
*
* @method SpinePlugin#add
* @since 3.19.0
*
*
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} [key] - The key of the Spine Skeleton this Game Object will use, as stored in the Spine Plugin.
@ -1095,16 +1095,16 @@ var SpinePlugin = new Class({
/**
* Creates a new Spine Game Object from the given configuration file and optionally adds it to the Scene.
*
*
* The x and y coordinate given is used to set the placement of the root Spine bone, which can vary from
* skeleton to skeleton. All rotation and scaling happens from the root bone placement. Spine Game Objects
* do not have a Phaser origin.
*
*
* If the Spine JSON file exported multiple Skeletons within it, then you can specify them by using a period
* character in the key. For example, if you loaded a Spine JSON using the key `monsters` and it contains
* multiple Skeletons, including one called `goblin` then you would use the key `monsters.goblin` to reference
* that.
*
*
* ```javascript
* let jelly = this.make.spine({
* x: 500, y: 500, key: 'jelly',

View file

@ -1,5 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Parser = void 0;
const dom = require("dts-dom");
const regexEndLine = /^(.*)\r\n|\n|\r/gm;
class Parser {

File diff suppressed because one or more lines are too long

View file

@ -1,5 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.publish = void 0;
const fs = require("fs-extra");
const path = require("path");
const Parser_1 = require("./Parser");

View file

@ -1 +1 @@
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":";;AAAA,+BAA+B;AAC/B,6BAA6B;AAC7B,qCAAkC;AAElC,SAAgB,OAAO,CAAC,IAAS,EAAE,IAAS;IACxC,6BAA6B;IAC7B,IAAI,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACtC,sBAAsB;IACtB,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACnC,yBAAyB;IACzB,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACjD,yBAAyB;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACrC,yBAAyB;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAEhC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;QAClC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;KAClC;IAED,IAAI,GAAG,GAAG,IAAI,eAAM,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAE1C,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,GAAG,CAAC,CAAC;AACtE,CAAC;AAnBD,0BAmBC;AAAA,CAAC"}
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,6BAA6B;AAC7B,qCAAkC;AAElC,SAAgB,OAAO,CAAC,IAAS,EAAE,IAAS;IACxC,6BAA6B;IAC7B,IAAI,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACtC,sBAAsB;IACtB,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACnC,yBAAyB;IACzB,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACjD,yBAAyB;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IACrC,yBAAyB;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAEhC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;QAClC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;KAClC;IAED,IAAI,GAAG,GAAG,IAAI,eAAM,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAE1C,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,EAAE,GAAG,CAAC,CAAC;AACtE,CAAC;AAnBD,0BAmBC;AAAA,CAAC"}

View file

@ -1,35 +0,0 @@
let scene:Phaser.Scene = new Phaser.Scene("");
let blitter = new Phaser.GameObjects.Blitter(scene, 10, 10);
let conf:GameConfig = {
type:Phaser.AUTO,
width: 100,
height: 100,
zoom: 1,
resolution: 1
}
let tex:Phaser.Textures.Texture = <any>null;
tex.source[0].setFilter(Phaser.Textures.FilterMode.LINEAR);
tex.setFilter(Phaser.Textures.FilterMode.LINEAR);
tex.setFilter(Phaser.Textures.NEAREST);
let sprite = new Phaser.GameObjects.Sprite(scene, 0, 0, "test");
class MyVec extends Phaser.Geom.Rectangle {
public extra() {
}
}
let p = new MyVec();
sprite.getBounds(p).extra();
let container = scene.add.container(0, 0);
container.getWorldTransformMatrix();

View file

@ -8,6 +8,7 @@
"preserveConstEnums": true,
"outFile": "./bin/game.js",
"sourceMap": true,
"moduleResolution": "node",
"lib": [
"dom",
"scripthost",
@ -19,6 +20,7 @@
"../../../types/phaser.d.ts"
],
"exclude": [
"node_modules"
"node_modules",
"../../../node_modules/@types"
]
}
}

View file

@ -226,7 +226,7 @@ var Animation = new Class({
*
* @param {(string|Phaser.Types.Animations.AnimationFrame[])} config - Either a string, in which case it will use all frames from a texture with the matching key, or an array of Animation Frame configuration objects.
*
* @return {Phaser.Animations.Animation} This Animation object.
* @return {this} This Animation object.
*/
addFrame: function (config)
{
@ -242,7 +242,7 @@ var Animation = new Class({
* @param {integer} index - The index to insert the frame at within the animation.
* @param {(string|Phaser.Types.Animations.AnimationFrame[])} config - Either a string, in which case it will use all frames from a texture with the matching key, or an array of Animation Frame configuration objects.
*
* @return {Phaser.Animations.Animation} This Animation object.
* @return {this} This Animation object.
*/
addFrameAt: function (index, config)
{
@ -591,7 +591,11 @@ var Animation = new Class({
if (component._reverse === !isReverse && component.repeatCounter > 0)
{
component.forward = isReverse;
if (!component._repeatDelay || component.pendingRepeat)
{
component.forward = isReverse;
}
this.repeatAnimation(component);
@ -698,7 +702,7 @@ var Animation = new Class({
*
* @param {Phaser.Animations.AnimationFrame} frame - The AnimationFrame to be removed.
*
* @return {Phaser.Animations.Animation} This Animation object.
* @return {this} This Animation object.
*/
removeFrame: function (frame)
{
@ -721,7 +725,7 @@ var Animation = new Class({
*
* @param {integer} index - The index in the AnimationFrame array
*
* @return {Phaser.Animations.Animation} This Animation object.
* @return {this} This Animation object.
*/
removeFrameAt: function (index)
{
@ -841,7 +845,7 @@ var Animation = new Class({
* @method Phaser.Animations.Animation#updateFrameSequence
* @since 3.0.0
*
* @return {Phaser.Animations.Animation} This Animation object.
* @return {this} This Animation object.
*/
updateFrameSequence: function ()
{
@ -898,7 +902,7 @@ var Animation = new Class({
* @method Phaser.Animations.Animation#pause
* @since 3.0.0
*
* @return {Phaser.Animations.Animation} This Animation object.
* @return {this} This Animation object.
*/
pause: function ()
{
@ -913,7 +917,7 @@ var Animation = new Class({
* @method Phaser.Animations.Animation#resume
* @since 3.0.0
*
* @return {Phaser.Animations.Animation} This Animation object.
* @return {this} This Animation object.
*/
resume: function ()
{

View file

@ -131,7 +131,7 @@ var AnimationManager = new Class({
* @param {string} key - The key under which the Animation should be added. The Animation will be updated with it. Must be unique.
* @param {Phaser.Animations.Animation} animation - The Animation which should be added to the Animation Manager.
*
* @return {Phaser.Animations.AnimationManager} This Animation Manager.
* @return {this} This Animation Manager.
*/
add: function (key, animation)
{
@ -139,7 +139,7 @@ var AnimationManager = new Class({
{
console.warn('Animation key exists: ' + key);
return;
return this;
}
animation.key = key;
@ -486,7 +486,7 @@ var AnimationManager = new Class({
* @fires Phaser.Animations.Events#PAUSE_ALL
* @since 3.0.0
*
* @return {Phaser.Animations.AnimationManager} This Animation Manager.
* @return {this} This Animation Manager.
*/
pauseAll: function ()
{
@ -509,7 +509,7 @@ var AnimationManager = new Class({
* @param {string} key - The key of the animation to play on the Game Object.
* @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Objects to play the animation on.
*
* @return {Phaser.Animations.AnimationManager} This Animation Manager.
* @return {this} This Animation Manager.
*/
play: function (key, child)
{
@ -522,7 +522,7 @@ var AnimationManager = new Class({
if (!anim)
{
return;
return this;
}
for (var i = 0; i < child.length; i++)
@ -568,7 +568,7 @@ var AnimationManager = new Class({
* @fires Phaser.Animations.Events#RESUME_ALL
* @since 3.0.0
*
* @return {Phaser.Animations.AnimationManager} This Animation Manager.
* @return {this} This Animation Manager.
*/
resumeAll: function ()
{
@ -596,7 +596,7 @@ var AnimationManager = new Class({
* @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} children - An array of Game Objects to play the animation on. They must have an Animation Component.
* @param {number} [stagger=0] - The amount of time, in milliseconds, to offset each play time by.
*
* @return {Phaser.Animations.AnimationManager} This Animation Manager.
* @return {this} This Animation Manager.
*/
staggerPlay: function (key, children, stagger)
{
@ -611,7 +611,7 @@ var AnimationManager = new Class({
if (!anim)
{
return;
return this;
}
for (var i = 0; i < children.length; i++)

View file

@ -60,7 +60,7 @@ var BaseCache = new Class({
* @param {string} key - The unique key by which the data added to the cache will be referenced.
* @param {*} data - The data to be stored in the cache.
*
* @return {Phaser.Cache.BaseCache} This BaseCache object.
* @return {this} This BaseCache object.
*/
add: function (key, data)
{
@ -131,7 +131,7 @@ var BaseCache = new Class({
*
* @param {string} key - The unique key of the item to remove from the cache.
*
* @return {Phaser.Cache.BaseCache} This BaseCache object.
* @return {this} This BaseCache object.
*/
remove: function (key)
{

View file

@ -609,7 +609,7 @@ var BaseCamera = new Class({
*
* @param {number} x - The horizontal coordinate to center on.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
centerOnX: function (x)
{
@ -636,7 +636,7 @@ var BaseCamera = new Class({
*
* @param {number} y - The vertical coordinate to center on.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
centerOnY: function (y)
{
@ -663,7 +663,7 @@ var BaseCamera = new Class({
* @param {number} x - The horizontal coordinate to center on.
* @param {number} y - The vertical coordinate to center on.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
centerOn: function (x, y)
{
@ -679,7 +679,7 @@ var BaseCamera = new Class({
* @method Phaser.Cameras.Scene2D.BaseCamera#centerToBounds
* @since 3.0.0
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
centerToBounds: function ()
{
@ -704,7 +704,7 @@ var BaseCamera = new Class({
* @method Phaser.Cameras.Scene2D.BaseCamera#centerToSize
* @since 3.0.0
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
centerToSize: function ()
{
@ -756,6 +756,10 @@ var BaseCamera = new Class({
var scrollY = this.scrollY;
var cameraW = this.width;
var cameraH = this.height;
var cullTop = this.y;
var cullBottom = cullTop + cameraH;
var cullLeft = this.x;
var cullRight = cullLeft + cameraW;
var culledObjects = this.culledObjects;
var length = renderableObjects.length;
@ -781,10 +785,6 @@ var BaseCamera = new Class({
var ty = (objectX * mvb + objectY * mvd + mvf);
var tw = ((objectX + objectW) * mva + (objectY + objectH) * mvc + mve);
var th = ((objectX + objectW) * mvb + (objectY + objectH) * mvd + mvf);
var cullTop = this.y;
var cullBottom = cullTop + cameraH;
var cullLeft = this.x;
var cullRight = cullLeft + cameraW;
if ((tw > cullLeft && tx < cullRight) && (th > cullTop && ty < cullBottom))
{
@ -872,7 +872,7 @@ var BaseCamera = new Class({
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group)} entries - The Game Object, or array of Game Objects, to be ignored by this Camera.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
ignore: function (entries)
{
@ -1042,7 +1042,7 @@ var BaseCamera = new Class({
* @method Phaser.Cameras.Scene2D.BaseCamera#removeBounds
* @since 3.0.0
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
removeBounds: function ()
{
@ -1065,7 +1065,7 @@ var BaseCamera = new Class({
*
* @param {number} [value=0] - The cameras angle of rotation, given in degrees.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setAngle: function (value)
{
@ -1089,7 +1089,7 @@ var BaseCamera = new Class({
*
* @param {(string|number|Phaser.Types.Display.InputColorObject)} [color='rgba(0,0,0,0)'] - The color value. In CSS, hex or numeric color notation.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setBackgroundColor: function (color)
{
@ -1130,7 +1130,7 @@ var BaseCamera = new Class({
* @param {integer} height - The height of the bounds, in pixels.
* @param {boolean} [centerOn=false] - If `true` the Camera will automatically be centered on the new bounds.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setBounds: function (x, y, width, height, centerOn)
{
@ -1188,7 +1188,7 @@ var BaseCamera = new Class({
*
* @param {string} [value=''] - The name of the Camera.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setName: function (value)
{
@ -1210,7 +1210,7 @@ var BaseCamera = new Class({
* @param {number} x - The top-left x coordinate of the Camera viewport.
* @param {number} [y=x] - The top-left y coordinate of the Camera viewport.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setPosition: function (x, y)
{
@ -1232,7 +1232,7 @@ var BaseCamera = new Class({
*
* @param {number} [value=0] - The rotation of the Camera, in radians.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setRotation: function (value)
{
@ -1253,7 +1253,7 @@ var BaseCamera = new Class({
*
* @param {boolean} value - `true` to round Camera pixels, `false` to not.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setRoundPixels: function (value)
{
@ -1272,7 +1272,7 @@ var BaseCamera = new Class({
*
* @param {Phaser.Scene} scene - The Scene the camera is bound to.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setScene: function (scene)
{
@ -1316,7 +1316,7 @@ var BaseCamera = new Class({
* @param {number} x - The x coordinate of the Camera in the game world.
* @param {number} [y=x] - The y coordinate of the Camera in the game world.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setScroll: function (x, y)
{
@ -1341,7 +1341,7 @@ var BaseCamera = new Class({
* @param {integer} width - The width of the Camera viewport.
* @param {integer} [height=width] - The height of the Camera viewport.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setSize: function (width, height)
{
@ -1372,7 +1372,7 @@ var BaseCamera = new Class({
* @param {integer} width - The width of the Camera viewport.
* @param {integer} [height=width] - The height of the Camera viewport.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setViewport: function (x, y, width, height)
{
@ -1399,7 +1399,7 @@ var BaseCamera = new Class({
*
* @param {number} [value=1] - The zoom value of the Camera. The minimum it can be is 0.001.
*
* @return {Phaser.Cameras.Scene2D.BaseCamera} This Camera instance.
* @return {this} This Camera instance.
*/
setZoom: function (value)
{

View file

@ -117,6 +117,16 @@ var Camera = new Class({
*/
this.panEffect = new Effects.Pan(this);
/**
* The Camera Rotate To effect handler.
* To rotate this camera see the `Camera.rotateTo` method.
*
* @name Phaser.Cameras.Scene2D.Camera#rotateToEffect
* @type {Phaser.Cameras.Scene2D.Effects.RotateTo}
* @since 3.23.0
*/
this.rotateToEffect = new Effects.RotateTo(this);
/**
* The Camera Zoom effect handler.
* To zoom this camera see the `Camera.zoom` method.
@ -337,7 +347,7 @@ var Camera = new Class({
* @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} [pipeline] - An optional WebGL Pipeline to render with, can be either a string which is the name of the pipeline, or a pipeline reference.
* @param {boolean} [renderToGame=true] - If you do not need the Camera to still render to the Game, set this parameter to `false`.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
setRenderToTexture: function (pipeline, renderToGame)
{
@ -379,7 +389,7 @@ var Camera = new Class({
*
* @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} [pipeline] - The WebGL Pipeline to render with, can be either a string which is the name of the pipeline, or a pipeline reference. Or if left empty it will clear the pipeline.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
setPipeline: function (pipeline)
{
@ -410,7 +420,7 @@ var Camera = new Class({
* @method Phaser.Cameras.Scene2D.Camera#clearRenderToTexture
* @since 3.13.0
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
clearRenderToTexture: function ()
{
@ -477,7 +487,7 @@ var Camera = new Class({
* @param {number} [width] - The width of the deadzone rectangle in pixels. If not specified the deadzone is removed.
* @param {number} [height] - The height of the deadzone rectangle in pixels.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
setDeadzone: function (width, height)
{
@ -533,7 +543,7 @@ var Camera = new Class({
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
fadeIn: function (duration, red, green, blue, callback, context)
{
@ -557,7 +567,7 @@ var Camera = new Class({
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
fadeOut: function (duration, red, green, blue, callback, context)
{
@ -581,7 +591,7 @@ var Camera = new Class({
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
fadeFrom: function (duration, red, green, blue, force, callback, context)
{
@ -605,7 +615,7 @@ var Camera = new Class({
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
fade: function (duration, red, green, blue, force, callback, context)
{
@ -629,7 +639,7 @@ var Camera = new Class({
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
flash: function (duration, red, green, blue, force, callback, context)
{
@ -651,7 +661,7 @@ var Camera = new Class({
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
shake: function (duration, intensity, force, callback, context)
{
@ -677,13 +687,37 @@ var Camera = new Class({
* the current camera scroll x coordinate and the current camera scroll y coordinate.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
pan: function (x, y, duration, ease, force, callback, context)
{
return this.panEffect.start(x, y, duration, ease, force, callback, context);
},
/**
* This effect will rotate the Camera so that the viewport finishes at the given angle in radians,
* over the duration and with the ease specified.
*
* @method Phaser.Cameras.Scene2D.Camera#rotateTo
* @since 3.23.0
*
* @param {number} radians - The destination angle in radians to rotate the Camera viewport to. If the angle is positive then the rotation is clockwise else anticlockwise
* @param {boolean} [shortestPath=false] - If shortest path is set to true the camera will rotate in the quickest direction clockwise or anti-clockwise.
* @param {integer} [duration=1000] - The duration of the effect in milliseconds.
* @param {(string|function)} [ease='Linear'] - The ease to use for the rotation. Can be any of the Phaser Easing constants or a custom function.
* @param {boolean} [force=false] - Force the rotation effect to start immediately, even if already running.
* @param {CameraRotateCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is,
* the current camera rotation angle in radians.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
*/
rotateTo: function (radians, shortestPath, duration, ease, force, callback, context)
{
return this.rotateToEffect.start(radians, shortestPath, duration, ease, force, callback, context);
},
/**
* This effect will zoom the Camera to the given scale, over the duration and with the ease specified.
*
@ -701,7 +735,7 @@ var Camera = new Class({
* the current camera scroll x coordinate and the current camera scroll y coordinate.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
zoomTo: function (zoom, duration, ease, force, callback, context)
{
@ -934,7 +968,7 @@ var Camera = new Class({
* @method Phaser.Cameras.Scene2D.Camera#stopFollow
* @since 3.0.0
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
stopFollow: function ()
{
@ -950,10 +984,11 @@ var Camera = new Class({
* @method Phaser.Cameras.Scene2D.Camera#resetFX
* @since 3.0.0
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
* @return {this} This Camera instance.
*/
resetFX: function ()
{
this.rotateToEffect.reset();
this.panEffect.reset();
this.shakeEffect.reset();
this.flashEffect.reset();
@ -976,6 +1011,7 @@ var Camera = new Class({
{
if (this.visible)
{
this.rotateToEffect.update(time, delta);
this.panEffect.update(time, delta);
this.zoomEffect.update(time, delta);
this.shakeEffect.update(time, delta);

View file

@ -395,7 +395,7 @@ var CameraManager = new Class({
*
* @param {(Phaser.Types.Cameras.Scene2D.CameraConfig|Phaser.Types.Cameras.Scene2D.CameraConfig[])} config - A Camera configuration object, or an array of them, to be added to this Camera Manager.
*
* @return {Phaser.Cameras.Scene2D.CameraManager} This Camera Manager instance.
* @return {this} This Camera Manager instance.
*/
fromJSON: function (config)
{

View file

@ -0,0 +1,427 @@
/**
* @author Jason Nicholls <nicholls.jason@gmail.com>
* @copyright 2018 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*/
var Clamp = require('../../../math/Clamp');
var Class = require('../../../utils/Class');
var Events = require('../events');
var EaseMap = require('../../../math/easing/EaseMap');
/**
* @classdesc
* A Camera Rotate effect.
*
* This effect will rotate the Camera so that the its viewport finishes at the given angle in radians,
* over the duration and with the ease specified.
*
* Camera rotation always takes place based on the Camera viewport. By default, rotation happens
* in the center of the viewport. You can adjust this with the `originX` and `originY` properties.
*
* Rotation influences the rendering of _all_ Game Objects visible by this Camera. However, it does not
* rotate the Camera viewport itself, which always remains an axis-aligned rectangle.
*
* Only the camera is rotates. None of the objects it is displaying are impacted, i.e. their positions do
* not change.
*
* The effect will dispatch several events on the Camera itself and you can also specify an `onUpdate` callback,
* which is invoked each frame for the duration of the effect if required.
*
* @class RotateTo
* @memberof Phaser.Cameras.Scene2D.Effects
* @constructor
* @since 3.23.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera this effect is acting upon.
*/
var RotateTo = new Class({
initialize:
function RotateTo (camera)
{
/**
* The Camera this effect belongs to.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#camera
* @type {Phaser.Cameras.Scene2D.Camera}
* @readonly
* @since 3.23.0
*/
this.camera = camera;
/**
* Is this effect actively running?
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#isRunning
* @type {boolean}
* @readonly
* @default false
* @since 3.23.0
*/
this.isRunning = false;
/**
* The duration of the effect, in milliseconds.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#duration
* @type {integer}
* @readonly
* @default 0
* @since 3.23.0
*/
this.duration = 0;
/**
* The starting angle to rotate the camera from.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#source
* @type {number}
* @since 3.23.0
*/
this.source = 0;
/**
* The constantly updated value based on the force.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#current
* @type {number}
* @since 3.23.0
*/
this.current = 0;
/**
* The destination angle in radians to rotate the camera to.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#destination
* @type {number}
* @since 3.23.0
*/
this.destination = 0;
/**
* The ease function to use during the Rotate.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#ease
* @type {function}
* @since 3.23.0
*/
this.ease;
/**
* If this effect is running this holds the current percentage of the progress, a value between 0 and 1.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#progress
* @type {number}
* @since 3.23.0
*/
this.progress = 0;
/**
* Effect elapsed timer.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#_elapsed
* @type {number}
* @private
* @since 3.23.0
*/
this._elapsed = 0;
/**
* @callback CameraRotateCallback
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera on which the effect is running.
* @param {number} progress - The progress of the effect. A value between 0 and 1.
* @param {number} angle - The Camera's new angle in radians.
*/
/**
* This callback is invoked every frame for the duration of the effect.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#_onUpdate
* @type {?CameraRotateCallback}
* @private
* @default null
* @since 3.23.0
*/
this._onUpdate;
/**
* On Complete callback scope.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#_onUpdateScope
* @type {any}
* @private
* @since 3.23.0
*/
this._onUpdateScope;
/**
* The direction of the rotation.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#clockwise
* @type {boolean}
* @since 3.23.0
*/
this.clockwise = true;
/**
* The shortest direction to the target rotation.
*
* @name Phaser.Cameras.Scene2D.Effects.RotateTo#shortestPath
* @type {boolean}
* @since 3.23.0
*/
this.shortestPath = false;
},
/**
* This effect will scroll the Camera so that the center of its viewport finishes at the given angle,
* over the duration and with the ease specified.
*
* @method Phaser.Cameras.Scene2D.Effects.RotateTo#start
* @fires Phaser.Cameras.Scene2D.Events#ROTATE_START
* @fires Phaser.Cameras.Scene2D.Events#ROTATE_COMPLETE
* @since 3.23.0
*
* @param {number} radians - The destination angle in radians to rotate the Camera viewport to. If the angle is positive then the rotation is clockwise else anticlockwise
* @param {boolean} [shortestPath=false] - If shortest path is set to true the camera will rotate in the quickest direction clockwise or anti-clockwise.
* @param {integer} [duration=1000] - The duration of the effect in milliseconds.
* @param {(string|function)} [ease='Linear'] - The ease to use for the Rotate. Can be any of the Phaser Easing constants or a custom function.
* @param {boolean} [force=false] - Force the rotation effect to start immediately, even if already running.
* @param {CameraRotateCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is,
* the current camera scroll x coordinate and the current camera scroll y coordinate.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started.
*/
start: function (radians, shortestPath, duration, ease, force, callback, context)
{
if (duration === undefined) { duration = 1000; }
if (ease === undefined) { ease = EaseMap.Linear; }
if (force === undefined) { force = false; }
if (callback === undefined) { callback = null; }
if (context === undefined) { context = this.camera.scene; }
if (shortestPath === undefined) { shortestPath = false; }
this.shortestPath = shortestPath;
var tmpDestination = radians;
if (radians < 0)
{
tmpDestination = -1 * radians;
this.clockwise = false;
}
else
{
this.clockwise = true;
}
var maxRad = (360 * Math.PI) / 180;
tmpDestination = tmpDestination - (Math.floor(tmpDestination / maxRad) * maxRad);
var cam = this.camera;
if (!force && this.isRunning)
{
return cam;
}
this.isRunning = true;
this.duration = duration;
this.progress = 0;
// Starting from
this.source = cam.rotation;
// Destination
this.destination = tmpDestination;
// Using this ease
if (typeof ease === 'string' && EaseMap.hasOwnProperty(ease))
{
this.ease = EaseMap[ease];
}
else if (typeof ease === 'function')
{
this.ease = ease;
}
this._elapsed = 0;
this._onUpdate = callback;
this._onUpdateScope = context;
if (this.shortestPath)
{
// The shortest path is true so calculate the quickest direction
var cwDist = 0;
var acwDist = 0;
if (this.destination > this.source)
{
cwDist = Math.abs(this.destination - this.source);
}
else
{
cwDist = (Math.abs(this.destination + maxRad) - this.source);
}
if (this.source > this.destination)
{
acwDist = Math.abs(this.source - this.destination);
}
else
{
acwDist = (Math.abs(this.source + maxRad) - this.destination);
}
if (cwDist < acwDist)
{
this.clockwise = true;
}
else if (cwDist > acwDist)
{
this.clockwise = false;
}
}
this.camera.emit(Events.ROTATE_START, this.camera, this, duration, tmpDestination);
return cam;
},
/**
* The main update loop for this effect. Called automatically by the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.RotateTo#update
* @since 3.23.0
*
* @param {integer} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function (time, delta)
{
if (!this.isRunning)
{
return;
}
this._elapsed += delta;
var progress = Clamp(this._elapsed / this.duration, 0, 1);
this.progress = progress;
var cam = this.camera;
if (this._elapsed < this.duration)
{
var v = this.ease(progress);
this.current = cam.rotation;
var distance = 0;
var maxRad = (360 * Math.PI) / 180;
var target = this.destination;
var current = this.current;
if (this.clockwise === false)
{
target = this.current;
current = this.destination;
}
if (target >= current)
{
distance = Math.abs(target - current);
}
else
{
distance = (Math.abs(target + maxRad) - current);
}
var r = 0;
if (this.clockwise)
{
r = (cam.rotation + (distance * v));
}
else
{
r = (cam.rotation - (distance * v));
}
cam.rotation = r;
if (this._onUpdate)
{
this._onUpdate.call(this._onUpdateScope, cam, progress, r);
}
}
else
{
cam.rotation = this.destination;
if (this._onUpdate)
{
this._onUpdate.call(this._onUpdateScope, cam, progress, this.destination);
}
this.effectComplete();
}
},
/**
* Called internally when the effect completes.
*
* @method Phaser.Cameras.Scene2D.Effects.RotateTo#effectComplete
* @since 3.23.0
*/
effectComplete: function ()
{
this._onUpdate = null;
this._onUpdateScope = null;
this.isRunning = false;
this.camera.emit(Events.ROTATE_COMPLETE, this.camera, this);
},
/**
* Resets this camera effect.
* If it was previously running, it stops instantly without calling its onComplete callback or emitting an event.
*
* @method Phaser.Cameras.Scene2D.Effects.RotateTo#reset
* @since 3.23.0
*/
reset: function ()
{
this.isRunning = false;
this._onUpdate = null;
this._onUpdateScope = null;
},
/**
* Destroys this effect, releasing it from the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.RotateTo#destroy
* @since 3.23.0
*/
destroy: function ()
{
this.reset();
this.camera = null;
this.source = null;
this.destination = null;
}
});
module.exports = RotateTo;

View file

@ -14,6 +14,7 @@ module.exports = {
Flash: require('./Flash'),
Pan: require('./Pan'),
Shake: require('./Shake'),
RotateTo: require('./RotateTo'),
Zoom: require('./Zoom')
};

View file

@ -0,0 +1,18 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2020 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
/**
* The Camera Rotate Complete Event.
*
* This event is dispatched by a Camera instance when the Rotate Effect completes.
*
* @event Phaser.Cameras.Scene2D.Events#ROTATE_COMPLETE
* @since 3.23.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on.
* @param {Phaser.Cameras.Scene2D.Effects.RotateTo} effect - A reference to the effect instance.
*/
module.exports = 'camerarotatecomplete';

View file

@ -0,0 +1,20 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2020 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
/**
* The Camera Rotate Start Event.
*
* This event is dispatched by a Camera instance when the Rotate Effect starts.
*
* @event Phaser.Cameras.Scene2D.Events#ROTATE_START
* @since 3.23.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera that the effect began on.
* @param {Phaser.Cameras.Scene2D.Effects.RotateTo} effect - A reference to the effect instance.
* @param {integer} duration - The duration of the effect.
* @param {number} destination - The destination value.
*/
module.exports = 'camerarotatestart';

View file

@ -21,6 +21,8 @@ module.exports = {
PAN_START: require('./PAN_START_EVENT'),
POST_RENDER: require('./POST_RENDER_EVENT'),
PRE_RENDER: require('./PRE_RENDER_EVENT'),
ROTATE_COMPLETE: require('./ROTATE_COMPLETE_EVENT'),
ROTATE_START: require('./ROTATE_START_EVENT'),
SHAKE_COMPLETE: require('./SHAKE_COMPLETE_EVENT'),
SHAKE_START: require('./SHAKE_START_EVENT'),
ZOOM_COMPLETE: require('./ZOOM_COMPLETE_EVENT'),

View file

@ -179,7 +179,7 @@ var FixedKeyControl = new Class({
* @method Phaser.Cameras.Controls.FixedKeyControl#start
* @since 3.0.0
*
* @return {Phaser.Cameras.Controls.FixedKeyControl} This Key Control instance.
* @return {this} This Key Control instance.
*/
start: function ()
{
@ -194,7 +194,7 @@ var FixedKeyControl = new Class({
* @method Phaser.Cameras.Controls.FixedKeyControl#stop
* @since 3.0.0
*
* @return {Phaser.Cameras.Controls.FixedKeyControl} This Key Control instance.
* @return {this} This Key Control instance.
*/
stop: function ()
{
@ -211,7 +211,7 @@ var FixedKeyControl = new Class({
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera to bind this Key Control to.
*
* @return {Phaser.Cameras.Controls.FixedKeyControl} This Key Control instance.
* @return {this} This Key Control instance.
*/
setCamera: function (camera)
{

View file

@ -273,7 +273,7 @@ var SmoothedKeyControl = new Class({
* @method Phaser.Cameras.Controls.SmoothedKeyControl#start
* @since 3.0.0
*
* @return {Phaser.Cameras.Controls.SmoothedKeyControl} This Key Control instance.
* @return {this} This Key Control instance.
*/
start: function ()
{
@ -288,7 +288,7 @@ var SmoothedKeyControl = new Class({
* @method Phaser.Cameras.Controls.SmoothedKeyControl#stop
* @since 3.0.0
*
* @return {Phaser.Cameras.Controls.SmoothedKeyControl} This Key Control instance.
* @return {this} This Key Control instance.
*/
stop: function ()
{
@ -305,7 +305,7 @@ var SmoothedKeyControl = new Class({
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera to bind this Key Control to.
*
* @return {Phaser.Cameras.Controls.SmoothedKeyControl} This Key Control instance.
* @return {this} This Key Control instance.
*/
setCamera: function (camera)
{

View file

@ -6,6 +6,7 @@
* @property {Phaser.Input.Keyboard.Key} [left] - The Key to be pressed that will move the Camera left.
* @property {Phaser.Input.Keyboard.Key} [right] - The Key to be pressed that will move the Camera right.
* @property {Phaser.Input.Keyboard.Key} [up] - The Key to be pressed that will move the Camera up.
* @property {Phaser.Input.Keyboard.Key} [down] - The Key to be pressed that will move the Camera down.
* @property {Phaser.Input.Keyboard.Key} [zoomIn] - The Key to be pressed that will zoom the Camera in.
* @property {Phaser.Input.Keyboard.Key} [zoomOut] - The Key to be pressed that will zoom the Camera out.
* @property {number} [zoomSpeed=0.01] - The speed at which the camera will zoom if the `zoomIn` or `zoomOut` keys are pressed.

View file

@ -6,7 +6,7 @@
/**
* Global constants.
*
*
* @ignore
*/
@ -14,13 +14,13 @@ var CONST = {
/**
* Phaser Release Version
*
*
* @name Phaser.VERSION
* @const
* @type {string}
* @since 3.0.0
*/
VERSION: '3.23.0-beta1',
VERSION: '3.50.0-beta.1',
BlendModes: require('./renderer/BlendModes'),
@ -28,7 +28,7 @@ var CONST = {
/**
* AUTO Detect Renderer.
*
*
* @name Phaser.AUTO
* @const
* @type {integer}
@ -38,7 +38,7 @@ var CONST = {
/**
* Canvas Renderer.
*
*
* @name Phaser.CANVAS
* @const
* @type {integer}
@ -48,7 +48,7 @@ var CONST = {
/**
* WebGL Renderer.
*
*
* @name Phaser.WEBGL
* @const
* @type {integer}
@ -58,7 +58,7 @@ var CONST = {
/**
* Headless Renderer.
*
*
* @name Phaser.HEADLESS
* @const
* @type {integer}
@ -69,7 +69,7 @@ var CONST = {
/**
* In Phaser the value -1 means 'forever' in lots of cases, this const allows you to use it instead
* to help you remember what the value is doing in your code.
*
*
* @name Phaser.FOREVER
* @const
* @type {integer}
@ -79,7 +79,7 @@ var CONST = {
/**
* Direction constant.
*
*
* @name Phaser.NONE
* @const
* @type {integer}
@ -89,7 +89,7 @@ var CONST = {
/**
* Direction constant.
*
*
* @name Phaser.UP
* @const
* @type {integer}
@ -99,7 +99,7 @@ var CONST = {
/**
* Direction constant.
*
*
* @name Phaser.DOWN
* @const
* @type {integer}
@ -109,7 +109,7 @@ var CONST = {
/**
* Direction constant.
*
*
* @name Phaser.LEFT
* @const
* @type {integer}
@ -119,7 +119,7 @@ var CONST = {
/**
* Direction constant.
*
*
* @name Phaser.RIGHT
* @const
* @type {integer}

View file

@ -396,7 +396,12 @@ var Config = new Class({
/**
* @const {integer} Phaser.Core.Config#batchSize - The default WebGL Batch size.
*/
this.batchSize = GetValue(renderConfig, 'batchSize', 2000);
this.batchSize = GetValue(renderConfig, 'batchSize', 4096);
/**
* @const {integer} Phaser.Core.Config#maxTextures - When in WebGL mode, this sets the maximum number of GPU Textures to use. The default, -1, will use all available units. The WebGL1 spec says all browsers should provide a minimum of 8.
*/
this.maxTextures = GetValue(renderConfig, 'maxTextures', -1);
/**
* @const {integer} Phaser.Core.Config#maxLights - The maximum number of lights allowed to be visible within range of a single Camera in the LightManager.

View file

@ -389,7 +389,7 @@ var Game = new Class({
*
* @method Phaser.Game#texturesReady
* @private
* @fires Phaser.Game#ready
* @fires Phaser.Game#READY
* @since 3.12.0
*/
texturesReady: function ()
@ -443,11 +443,11 @@ var Game = new Class({
* It will then render each Scene in turn, via the Renderer. This process emits `prerender` and `postrender` events.
*
* @method Phaser.Game#step
* @fires Phaser.Core.Events#PRE_STEP_EVENT
* @fires Phaser.Core.Events#STEP_EVENT
* @fires Phaser.Core.Events#POST_STEP_EVENT
* @fires Phaser.Core.Events#PRE_RENDER_EVENT
* @fires Phaser.Core.Events#POST_RENDER_EVENT
* @fires Phaser.Core.Events#PRE_STEP
* @fires Phaser.Core.Events#STEP
* @fires Phaser.Core.Events#POST_STEP
* @fires Phaser.Core.Events#PRE_RENDER
* @fires Phaser.Core.Events#POST_RENDER
* @since 3.0.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
@ -510,8 +510,8 @@ var Game = new Class({
* This process emits `prerender` and `postrender` events, even though nothing actually displays.
*
* @method Phaser.Game#headlessStep
* @fires Phaser.Game#prerenderEvent
* @fires Phaser.Game#postrenderEvent
* @fires Phaser.Game#PRE_RENDER
* @fires Phaser.Game#POST_RENDER
* @since 3.2.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
@ -672,7 +672,7 @@ var Game = new Class({
runDestroy: function ()
{
this.scene.destroy();
this.events.emit(Events.DESTROY);
this.events.removeAllListeners();

View file

@ -644,7 +644,7 @@ var TimeStep = new Class({
{
if (this.running)
{
this.sleep();
return;
}
else if (seamless)
{

View file

@ -7,7 +7,7 @@
* @property {number} [zoom=1] - Simple scale applied to the game canvas. 2 is double size, 0.5 is half size, etc.
* @property {number} [resolution=1] - The size of each game pixel, in canvas pixels. Values larger than 1 are "high" resolution.
* @property {number} [type=CONST.AUTO] - Which renderer to use. Phaser.AUTO, Phaser.CANVAS, Phaser.HEADLESS, or Phaser.WEBGL. AUTO picks WEBGL if available, otherwise CANVAS.
* @property {(HTMLElement|string)} [parent=null] - The DOM element that will contain the game canvas, or its `id`. If undefined or if the named element doesn't exist, the game canvas is inserted directly into the document body. If `null` no parent will be used and you are responsible for adding the canvas to your environment.
* @property {(HTMLElement|string)} [parent=undefined] - The DOM element that will contain the game canvas, or its `id`. If undefined, or if the named element doesn't exist, the game canvas is appended to the document body. If `null` no parent will be used and you are responsible for adding the canvas to the dom.
* @property {HTMLCanvasElement} [canvas=null] - Provide your own Canvas element for Phaser to use instead of creating one.
* @property {string} [canvasStyle=null] - CSS styles to apply to the game canvas instead of Phasers default styles.
* @property {boolean}[customEnvironment=false] - Is Phaser running under a custom (non-native web) environment? If so, set this to `true` to skip internal Feature detection. If `true` the `renderType` cannot be left as `AUTO`.

View file

@ -5,7 +5,7 @@
* @property {boolean} [antialias=true] - When set to `true`, WebGL uses linear interpolation to draw scaled or rotated textures, giving a smooth appearance. When set to `false`, WebGL uses nearest-neighbor interpolation, giving a crisper appearance. `false` also disables antialiasing of the game canvas itself, if the browser supports it, when the game canvas is scaled.
* @property {boolean} [antialiasGL=true] - Sets the `antialias` property when the WebGL context is created. Setting this value does not impact any subsequent textures that are created, or the canvas style attributes.
* @property {boolean} [desynchronized=false] - When set to `true` it will create a desynchronized context for both 2D and WebGL. See https://developers.google.com/web/updates/2019/05/desynchronized for details.
* @property {boolean} [pixelArt=false] - Sets `antialias` and `roundPixels` to true. This is the best setting for pixel-art games.
* @property {boolean} [pixelArt=false] - Sets `antialias` to false and `roundPixels` to true. This is the best setting for pixel-art games.
* @property {boolean} [roundPixels=false] - Draw texture-based Game Objects at only whole-integer positions. Game Objects without textures, like Graphics, ignore this property.
* @property {boolean} [transparent=false] - Whether the game canvas will be transparent. Boolean that indicates if the canvas contains an alpha channel. If set to false, the browser now knows that the backdrop is always opaque, which can speed up drawing of transparent content and images.
* @property {boolean} [clearBeforeRender=true] - Whether the game canvas will be cleared between each rendering frame.
@ -14,5 +14,6 @@
* @property {string} [powerPreference='default'] - "high-performance", "low-power" or "default". A hint to the browser on how much device power the game might use.
* @property {integer} [batchSize=2000] - The default WebGL batch size.
* @property {integer} [maxLights=10] - The maximum number of lights allowed to be visible within range of a single Camera in the LightManager.
* @property {integer} [maxTextures=-1] - When in WebGL mode, this sets the maximum number of GPU Textures to use. The default, -1, will use all available units. The WebGL1 spec says all browsers should provide a minimum of 8.
* @property {string} [mipmapFilter='LINEAR'] - The mipmap magFilter to be used when creating WebGL textures.
*/

View file

@ -489,17 +489,16 @@ var Curve = new Class({
return this.getTangent(t, out);
},
// Given a distance in pixels, get a t to find p.
/**
* [description]
* Given a distance in pixels, get a t to find p.
*
* @method Phaser.Curves.Curve#getTFromDistance
* @since 3.0.0
*
* @param {integer} distance - [description]
* @param {integer} [divisions] - [description]
* @param {integer} distance - The distance, in pixels.
* @param {integer} [divisions] - Optional amount of divisions.
*
* @return {number} [description]
* @return {number} The distance.
*/
getTFromDistance: function (distance, divisions)
{
@ -511,19 +510,17 @@ var Curve = new Class({
return this.getUtoTmapping(0, distance, divisions);
},
// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant
/**
* [description]
* Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant.
*
* @method Phaser.Curves.Curve#getUtoTmapping
* @since 3.0.0
*
* @param {number} u - [description]
* @param {integer} distance - [description]
* @param {integer} [divisions] - [description]
* @param {number} u - A float between 0 and 1.
* @param {integer} distance - The distance, in pixels.
* @param {integer} [divisions] - Optional amount of divisions.
*
* @return {number} [description]
* @return {number} The equidistant value.
*/
getUtoTmapping: function (u, distance, divisions)
{

View file

@ -160,14 +160,14 @@ var EllipseCurve = new Class({
},
/**
* [description]
* Get the resolution of the curve.
*
* @method Phaser.Curves.Ellipse#getResolution
* @since 3.0.0
*
* @param {number} divisions - [description]
* @param {number} divisions - Optional divisions value.
*
* @return {number} [description]
* @return {number} The curve resolution.
*/
getResolution: function (divisions)
{
@ -258,7 +258,7 @@ var EllipseCurve = new Class({
*
* @param {number} value - The horizontal radius of this curve.
*
* @return {Phaser.Curves.Ellipse} This curve object.
* @return {this} This curve object.
*/
setXRadius: function (value)
{
@ -275,7 +275,7 @@ var EllipseCurve = new Class({
*
* @param {number} value - The vertical radius of this curve.
*
* @return {Phaser.Curves.Ellipse} This curve object.
* @return {this} This curve object.
*/
setYRadius: function (value)
{
@ -292,11 +292,11 @@ var EllipseCurve = new Class({
*
* @param {number} value - The width of this curve.
*
* @return {Phaser.Curves.Ellipse} This curve object.
* @return {this} This curve object.
*/
setWidth: function (value)
{
this.xRadius = value * 2;
this.xRadius = value / 2;
return this;
},
@ -309,11 +309,11 @@ var EllipseCurve = new Class({
*
* @param {number} value - The height of this curve.
*
* @return {Phaser.Curves.Ellipse} This curve object.
* @return {this} This curve object.
*/
setHeight: function (value)
{
this.yRadius = value * 2;
this.yRadius = value / 2;
return this;
},
@ -326,7 +326,7 @@ var EllipseCurve = new Class({
*
* @param {number} value - The start angle of this curve, in radians.
*
* @return {Phaser.Curves.Ellipse} This curve object.
* @return {this} This curve object.
*/
setStartAngle: function (value)
{
@ -343,7 +343,7 @@ var EllipseCurve = new Class({
*
* @param {number} value - The end angle of this curve, in radians.
*
* @return {Phaser.Curves.Ellipse} This curve object.
* @return {this} This curve object.
*/
setEndAngle: function (value)
{
@ -360,7 +360,7 @@ var EllipseCurve = new Class({
*
* @param {boolean} value - The clockwise state of this curve.
*
* @return {Phaser.Curves.Ellipse} This curve object.
* @return {this} This curve object.
*/
setClockwise: function (value)
{
@ -377,7 +377,7 @@ var EllipseCurve = new Class({
*
* @param {number} value - The rotation of this curve, in radians.
*
* @return {Phaser.Curves.Ellipse} This curve object.
* @return {this} This curve object.
*/
setRotation: function (value)
{

View file

@ -194,19 +194,17 @@ var LineCurve = new Class({
return tangent.normalize();
},
// Override default Curve.getUtoTmapping
/**
* [description]
* Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant.
*
* @method Phaser.Curves.Line#getUtoTmapping
* @since 3.0.0
*
* @param {number} u - [description]
* @param {integer} distance - [description]
* @param {integer} [divisions] - [description]
* @param {number} u - A float between 0 and 1.
* @param {integer} distance - The distance, in pixels.
* @param {integer} [divisions] - Optional amount of divisions.
*
* @return {number} [description]
* @return {number} The equidistant value.
*/
getUtoTmapping: function (u, distance, divisions)
{

View file

@ -11,7 +11,7 @@ var Vector2 = require('../math/Vector2');
/**
* @classdesc
* [description]
* A quadratic Bézier curve constructed from two control points.
*
* @class QuadraticBezier
* @extends Phaser.Curves.Curve
@ -41,7 +41,7 @@ var QuadraticBezier = new Class({
}
/**
* [description]
* The start point.
*
* @name Phaser.Curves.QuadraticBezier#p0
* @type {Phaser.Math.Vector2}
@ -50,7 +50,7 @@ var QuadraticBezier = new Class({
this.p0 = p0;
/**
* [description]
* The first control point.
*
* @name Phaser.Curves.QuadraticBezier#p1
* @type {Phaser.Math.Vector2}
@ -59,7 +59,7 @@ var QuadraticBezier = new Class({
this.p1 = p1;
/**
* [description]
* The second control point.
*
* @name Phaser.Curves.QuadraticBezier#p2
* @type {Phaser.Math.Vector2}
@ -88,14 +88,14 @@ var QuadraticBezier = new Class({
},
/**
* [description]
* Get the resolution of the curve.
*
* @method Phaser.Curves.QuadraticBezier#getResolution
* @since 3.2.0
*
* @param {number} divisions - [description]
* @param {number} divisions - Optional divisions value.
*
* @return {number} [description]
* @return {number} The curve resolution.
*/
getResolution: function (divisions)
{
@ -130,7 +130,10 @@ var QuadraticBezier = new Class({
},
/**
* [description]
* Draws this curve on the given Graphics object.
*
* The curve is drawn using `Graphics.strokePoints` so will be drawn at whatever the present Graphics stroke color is.
* The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it.
*
* @method Phaser.Curves.QuadraticBezier#draw
* @since 3.2.0

View file

@ -56,7 +56,7 @@ var SplineCurve = new Class({
*
* @param {(Phaser.Math.Vector2[]|number[]|number[][])} points - The points that configure the curve.
*
* @return {Phaser.Curves.Spline} This curve object.
* @return {this} This curve object.
*/
addPoints: function (points)
{
@ -128,14 +128,14 @@ var SplineCurve = new Class({
},
/**
* [description]
* Get the resolution of the curve.
*
* @method Phaser.Curves.Spline#getResolution
* @since 3.0.0
*
* @param {number} divisions - [description]
* @param {number} divisions - Optional divisions value.
*
* @return {number} [description]
* @return {number} The curve resolution.
*/
getResolution: function (divisions)
{

View file

@ -137,7 +137,7 @@ var Path = new Class({
*
* @param {Phaser.Curves.Curve} curve - The Curve to append.
*
* @return {Phaser.Curves.Path} This Path object.
* @return {this} This Path object.
*/
add: function (curve)
{
@ -156,7 +156,7 @@ var Path = new Class({
* @param {boolean} [clockwise=false] - `true` to create a clockwise circle as opposed to a counter-clockwise circle.
* @param {number} [rotation=0] - The rotation of the circle in degrees.
*
* @return {Phaser.Curves.Path} This Path object.
* @return {this} This Path object.
*/
circleTo: function (radius, clockwise, rotation)
{
@ -175,7 +175,7 @@ var Path = new Class({
* @method Phaser.Curves.Path#closePath
* @since 3.0.0
*
* @return {Phaser.Curves.Path} This Path object.
* @return {this} This Path object.
*/
closePath: function ()
{
@ -205,7 +205,7 @@ var Path = new Class({
* @param {number} [control2X] - The x coordinate of the second control point. Not used if Vector2s are provided as the first 3 arguments.
* @param {number} [control2Y] - The y coordinate of the second control point. Not used if Vector2s are provided as the first 3 arguments.
*
* @return {Phaser.Curves.Path} This Path object.
* @return {this} This Path object.
*/
cubicBezierTo: function (x, y, control1X, control1Y, control2X, control2Y)
{
@ -244,7 +244,7 @@ var Path = new Class({
* @param {number} [controlX] - If `x` is not a `Vector2`, the X coordinate of the first control point.
* @param {number} [controlY] - If `x` is not a `Vector2`, the Y coordinate of the first control point.
*
* @return {Phaser.Curves.Path} This Path object.
* @return {this} This Path object.
*/
quadraticBezierTo: function (x, y, controlX, controlY)
{
@ -310,7 +310,7 @@ var Path = new Class({
* @param {boolean} [clockwise=false] - Whether the ellipse angles are given as clockwise (`true`) or counter-clockwise (`false`).
* @param {number} [rotation=0] - The rotation of the ellipse, in degrees.
*
* @return {Phaser.Curves.Path} This Path object.
* @return {this} This Path object.
*/
ellipseTo: function (xRadius, yRadius, startAngle, endAngle, clockwise, rotation)
{
@ -339,7 +339,7 @@ var Path = new Class({
*
* @param {Phaser.Types.Curves.JSONPath} data - The JSON object containing the Path data.
*
* @return {Phaser.Curves.Path} This Path object.
* @return {this} This Path object.
*/
fromJSON: function (data)
{
@ -693,6 +693,46 @@ var Path = new Class({
return out.copy(this.startPoint);
},
/**
* Gets a unit vector tangent at a relative position on the path.
*
* @method Phaser.Curves.Path#getTangent
* @since 3.23.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} t - The relative position on the path, [0..1].
* @param {Phaser.Math.Vector2} [out] - A vector to store the result in.
*
* @return {Phaser.Math.Vector2} Vector approximating the tangent line at the point t (delta +/- 0.0001)
*/
getTangent: function (t, out)
{
if (out === undefined) { out = new Vector2(); }
var d = t * this.getLength();
var curveLengths = this.getCurveLengths();
var i = 0;
while (i < curveLengths.length)
{
if (curveLengths[i] >= d)
{
var diff = curveLengths[i] - d;
var curve = this.curves[i];
var segmentLength = curve.getLength();
var u = (segmentLength === 0) ? 0 : 1 - diff / segmentLength;
return curve.getTangentAt(u, out);
}
i++;
}
return null;
},
/**
* Creates a line curve from the previous end point to x/y.
*
@ -702,7 +742,7 @@ var Path = new Class({
* @param {(number|Phaser.Math.Vector2)} x - The X coordinate of the line's end point, or a `Vector2` containing the entire end point.
* @param {number} [y] - The Y coordinate of the line's end point, if a number was passed as the X parameter.
*
* @return {Phaser.Curves.Path} This Path object.
* @return {this} This Path object.
*/
lineTo: function (x, y)
{
@ -728,7 +768,7 @@ var Path = new Class({
*
* @param {Phaser.Math.Vector2[]} points - The points the newly created spline curve should consist of.
*
* @return {Phaser.Curves.Path} This Path object.
* @return {this} This Path object.
*/
splineTo: function (points)
{
@ -746,9 +786,9 @@ var Path = new Class({
* @since 3.0.0
*
* @param {(number|Phaser.Math.Vector2)} x - The X coordinate of the position to move the path's end point to, or a `Vector2` containing the entire new end point.
* @param {number} y - The Y coordinate of the position to move the path's end point to, if a number was passed as the X coordinate.
* @param {number} [y] - The Y coordinate of the position to move the path's end point to, if a number was passed as the X coordinate.
*
* @return {Phaser.Curves.Path} This Path object.
* @return {this} This Path object.
*/
moveTo: function (x, y)
{

View file

@ -28,7 +28,7 @@ var Events = require('./events');
* @since 3.0.0
*
* @param {object} parent - The object that this DataManager belongs to.
* @param {Phaser.Events.EventEmitter} eventEmitter - The DataManager's event emitter.
* @param {Phaser.Events.EventEmitter} [eventEmitter] - The DataManager's event emitter.
*/
var DataManager = new Class({
@ -255,7 +255,7 @@ var DataManager = new Class({
* @param {(string|object)} key - The key to set the value for. Or an object or key value pairs. If an object the `data` argument is ignored.
* @param {*} data - The value to set for the given key. If an object is provided as the key this argument is ignored.
*
* @return {Phaser.Data.DataManager} This DataManager object.
* @return {this} This DataManager object.
*/
set: function (key, data)
{
@ -279,6 +279,72 @@ var DataManager = new Class({
return this;
},
/**
* Increase a value for the given key. If the key doesn't already exist in the Data Manager then it is increased from 0.
*
* When the value is first set, a `setdata` event is emitted.
*
* @method Phaser.Data.DataManager#inc
* @fires Phaser.Data.Events#SET_DATA
* @fires Phaser.Data.Events#CHANGE_DATA
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
* @since 3.23.0
*
* @param {(string|object)} key - The key to increase the value for.
* @param {*} [data] - The value to increase for the given key.
*
* @return {Phaser.Data.DataManager} This DataManager object.
*/
inc: function (key, data)
{
if (this._frozen)
{
return this;
}
if (data === undefined)
{
data = 1;
}
var value = this.get(key);
if (value === undefined)
{
value = 0;
}
this.set(key, (value + data));
return this;
},
/**
* Toggle a boolean value for the given key. If the key doesn't already exist in the Data Manager then it is toggled from false.
*
* When the value is first set, a `setdata` event is emitted.
*
* @method Phaser.Data.DataManager#toggle
* @fires Phaser.Data.Events#SET_DATA
* @fires Phaser.Data.Events#CHANGE_DATA
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
* @since 3.23.0
*
* @param {(string|object)} key - The key to toggle the value for.
*
* @return {Phaser.Data.DataManager} This DataManager object.
*/
toggle: function (key)
{
if (this._frozen)
{
return this;
}
this.set(key, !this.get(key));
return this;
},
/**
* Internal value setter, called automatically by the `set` method.
*
@ -292,7 +358,7 @@ var DataManager = new Class({
* @param {string} key - The key to set the value for.
* @param {*} data - The value to set.
*
* @return {Phaser.Data.DataManager} This DataManager object.
* @return {this} This DataManager object.
*/
setValue: function (key, data)
{
@ -356,7 +422,7 @@ var DataManager = new Class({
* @param {*} [context] - Value to use as `this` when executing callback.
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the game object, key, and data.
*
* @return {Phaser.Data.DataManager} This DataManager object.
* @return {this} This DataManager object.
*/
each: function (callback, context)
{
@ -393,7 +459,7 @@ var DataManager = new Class({
* @param {Object.<string, *>} data - The data to merge.
* @param {boolean} [overwrite=true] - Whether to overwrite existing data. Defaults to true.
*
* @return {Phaser.Data.DataManager} This DataManager object.
* @return {this} This DataManager object.
*/
merge: function (data, overwrite)
{
@ -429,7 +495,7 @@ var DataManager = new Class({
*
* @param {(string|string[])} key - The key to remove, or an array of keys to remove.
*
* @return {Phaser.Data.DataManager} This DataManager object.
* @return {this} This DataManager object.
*/
remove: function (key)
{
@ -463,7 +529,7 @@ var DataManager = new Class({
*
* @param {string} key - The key to set the value for.
*
* @return {Phaser.Data.DataManager} This DataManager object.
* @return {this} This DataManager object.
*/
removeValue: function (key)
{
@ -535,7 +601,7 @@ var DataManager = new Class({
*
* @param {boolean} value - Whether to freeze or unfreeze the Data Manager.
*
* @return {Phaser.Data.DataManager} This DataManager object.
* @return {this} This DataManager object.
*/
setFreeze: function (value)
{
@ -550,7 +616,7 @@ var DataManager = new Class({
* @method Phaser.Data.DataManager#reset
* @since 3.0.0
*
* @return {Phaser.Data.DataManager} This DataManager object.
* @return {this} This DataManager object.
*/
reset: function ()
{

View file

@ -53,7 +53,7 @@ function init ()
{
var ua = navigator.userAgent;
if (/Edge\/\d+/.test(ua))
if ((/Edge\/\d+/).test(ua))
{
Browser.edge = true;
}

View file

@ -63,23 +63,23 @@ function init ()
{
var ua = navigator.userAgent;
if (/Windows/.test(ua))
if ((/Windows/).test(ua))
{
OS.windows = true;
}
else if (/Mac OS/.test(ua) && !(/like Mac OS/.test(ua)))
else if ((/Mac OS/).test(ua) && !((/like Mac OS/).test(ua)))
{
OS.macOS = true;
}
else if (/Android/.test(ua))
else if ((/Android/).test(ua))
{
OS.android = true;
}
else if (/Linux/.test(ua))
else if ((/Linux/).test(ua))
{
OS.linux = true;
}
else if (/iP[ao]d|iPhone/i.test(ua))
else if ((/iP[ao]d|iPhone/i).test(ua))
{
OS.iOS = true;
@ -90,19 +90,19 @@ function init ()
OS.iPhone = ua.toLowerCase().indexOf('iphone') !== -1;
OS.iPad = ua.toLowerCase().indexOf('ipad') !== -1;
}
else if (/Kindle/.test(ua) || (/\bKF[A-Z][A-Z]+/).test(ua) || (/Silk.*Mobile Safari/).test(ua))
else if ((/Kindle/).test(ua) || (/\bKF[A-Z][A-Z]+/).test(ua) || (/Silk.*Mobile Safari/).test(ua))
{
OS.kindle = true;
// This will NOT detect early generations of Kindle Fire, I think there is no reliable way...
// E.g. "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-80) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true"
}
else if (/CrOS/.test(ua))
else if ((/CrOS/).test(ua))
{
OS.chromeOS = true;
}
if (/Windows Phone/i.test(ua) || (/IEMobile/i).test(ua))
if ((/Windows Phone/i).test(ua) || (/IEMobile/i).test(ua))
{
OS.android = false;
OS.iOS = false;
@ -119,7 +119,7 @@ function init ()
}
// Windows Phone / Table reset
if (OS.windowsPhone || ((/Windows NT/i.test(ua)) && (/Touch/i.test(ua))))
if (OS.windowsPhone || (((/Windows NT/i).test(ua)) && ((/Touch/i).test(ua))))
{
OS.desktop = false;
}

View file

@ -0,0 +1,38 @@
/**
* @author samme
* @copyright 2020 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var GetBottom = require('./GetBottom');
var GetLeft = require('./GetLeft');
var GetRight = require('./GetRight');
var GetTop = require('./GetTop');
/**
* Returns the unrotated bounds of the Game Object as a rectangle.
*
* @function Phaser.Display.Bounds.GetBounds
* @since 3.24.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to get the bounds value from.
* @param {(Phaser.Geom.Rectangle|object)} [output] - An object to store the values in.
*
* @return {(Phaser.Geom.Rectangle|object)} - The bounds of the Game Object.
*/
var GetBounds = function (gameObject, output)
{
if (output === undefined) { output = {}; }
var left = GetLeft(gameObject);
var top = GetTop(gameObject);
output.x = left;
output.y = top;
output.width = GetRight(gameObject) - left;
output.height = GetBottom(gameObject) - top;
return output;
};
module.exports = GetBounds;

View file

@ -12,6 +12,7 @@ module.exports = {
CenterOn: require('./CenterOn'),
GetBottom: require('./GetBottom'),
GetBounds: require('./GetBounds'),
GetCenterX: require('./GetCenterX'),
GetCenterY: require('./GetCenterY'),
GetLeft: require('./GetLeft'),
@ -25,5 +26,5 @@ module.exports = {
SetLeft: require('./SetLeft'),
SetRight: require('./SetRight'),
SetTop: require('./SetTop')
};

View file

@ -0,0 +1,23 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2020 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
/**
* Given a hex color value, such as 0xff00ff (for purple), it will return a
* numeric representation of it (i.e. 16711935) for use in WebGL tinting.
*
* @function Phaser.Display.Color.GetColorFromValue
* @since 3.50.0
*
* @param {number} red - The hex color value, such as 0xff0000.
*
* @return {number} The combined color value.
*/
var GetColorFromValue = function (value)
{
return (value >> 16) + (value & 0xff00) + ((value & 0xff) << 16);
};
module.exports = GetColorFromValue;

View file

@ -10,6 +10,7 @@ Color.ColorToRGBA = require('./ColorToRGBA');
Color.ComponentToHex = require('./ComponentToHex');
Color.GetColor = require('./GetColor');
Color.GetColor32 = require('./GetColor32');
Color.GetColorFromValue = require('./GetColorFromValue');
Color.HexStringToColor = require('./HexStringToColor');
Color.HSLToColor = require('./HSLToColor');
Color.HSVColorWheel = require('./HSVColorWheel');

View file

@ -33,7 +33,7 @@ var AddToDOM = function (element, parent)
target = parent;
}
}
else if (element.parentElement)
else if (element.parentElement || parent === null)
{
return element;
}

View file

@ -169,7 +169,7 @@ var GameObject = new Class({
* If this Game Object is enabled for Arcade or Matter Physics then this property will contain a reference to a Physics Body.
*
* @name Phaser.GameObjects.GameObject#body
* @type {?(object|Phaser.Physics.Arcade.Body|MatterJS.BodyType)}
* @type {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|MatterJS.BodyType)}
* @default null
* @since 3.0.0
*/
@ -330,6 +330,65 @@ var GameObject = new Class({
return this;
},
/**
* Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0.
*
* If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled
* before setting the value.
*
* If the key doesn't already exist in the Data Manager then it is created.
*
* When the value is first set, a `setdata` event is emitted from this Game Object.
*
* @method Phaser.GameObjects.GameObject#incData
* @since 3.23.0
*
* @param {(string|object)} key - The key to increase the value for.
* @param {*} [data] - The value to increase for the given key.
*
* @return {this} This GameObject.
*/
incData: function (key, value)
{
if (!this.data)
{
this.data = new DataManager(this);
}
this.data.inc(key, value);
return this;
},
/**
* Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false.
*
* If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled
* before setting the value.
*
* If the key doesn't already exist in the Data Manager then it is created.
*
* When the value is first set, a `setdata` event is emitted from this Game Object.
*
* @method Phaser.GameObjects.GameObject#toggleData
* @since 3.23.0
*
* @param {(string|object)} key - The key to toggle the value for.
*
* @return {this} This GameObject.
*/
toggleData: function (key)
{
if (!this.data)
{
this.data = new DataManager(this);
}
this.data.toggle(key);
return this;
},
/**
* Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist.
*
@ -383,18 +442,27 @@ var GameObject = new Class({
*
* You can also provide an Input Configuration Object as the only argument to this method.
*
* @example
* sprite.setInteractive();
*
* @example
* sprite.setInteractive(new Phaser.Geom.Circle(45, 46, 45), Phaser.Geom.Circle.Contains);
*
* @example
* graphics.setInteractive(new Phaser.Geom.Rectangle(0, 0, 128, 128), Phaser.Geom.Rectangle.Contains);
*
* @method Phaser.GameObjects.GameObject#setInteractive
* @since 3.0.0
*
* @param {(Phaser.Types.Input.InputConfiguration|any)} [shape] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used.
* @param {Phaser.Types.Input.HitAreaCallback} [callback] - A callback to be invoked when the Game Object is interacted with. If you provide a shape you must also provide a callback.
* @param {(Phaser.Types.Input.InputConfiguration|any)} [hitArea] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not given it will try to create a Rectangle based on the texture frame.
* @param {Phaser.Types.Input.HitAreaCallback} [callback] - The callback that determines if the pointer is within the Hit Area shape or not. If you provide a shape you must also provide a callback.
* @param {boolean} [dropZone=false] - Should this Game Object be treated as a drop zone target?
*
* @return {this} This GameObject.
*/
setInteractive: function (shape, callback, dropZone)
setInteractive: function (hitArea, hitAreaCallback, dropZone)
{
this.scene.sys.input.enable(this, shape, callback, dropZone);
this.scene.sys.input.enable(this, hitArea, hitAreaCallback, dropZone);
return this;
},

View file

@ -112,6 +112,8 @@ var GameObjectFactory = new Class({
* @method Phaser.GameObjects.GameObjectFactory#existing
* @since 3.0.0
*
* @generic {Phaser.GameObjects.GameObject} G - [child,$return]
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.Group)} child - The child to be added to this Scene.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that was added.

View file

@ -0,0 +1,53 @@
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2020 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
/**
* Renders one character of the Bitmap Text to the WebGL Pipeline.
*
* @function BatchChar
* @since 3.50.0
* @private
*
* @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The BitmapText Game Object.
* @param {Phaser.GameObjects.BitmapText} src - The BitmapText Game Object.
* @param {Phaser.Types.GameObjects.BitmapText.BitmapTextCharacter} char - The character to render.
* @param {Phaser.Types.GameObjects.BitmapText.BitmapFontCharacterData} glyph - The character glyph.
* @param {number} offsetX - The x offset.
* @param {number} offsetY - The y offset.
* @param {Phaser.GameObjects.Components.TransformMatrix} calcMatrix - The transform matrix.
* @param {boolean} roundPixels - Round the transform values or not?
* @param {number} tintTL - Top-left tint value.
* @param {number} tintTR - Top-right tint value.
* @param {number} tintBL - Bottom-left tint value.
* @param {number} tintBR - Bottom-right tint value.
* @param {number} tintEffect - The tint effect mode.
* @param {WebGLTexture} texture - The WebGL texture.
* @param {number} textureUnit - The texture unit.
*/
var BatchChar = function (pipeline, src, char, glyph, offsetX, offsetY, calcMatrix, roundPixels, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit)
{
var x = (char.x - src.displayOriginX) + offsetX;
var y = (char.y - src.displayOriginY) + offsetY;
var xw = x + char.w;
var yh = y + char.h;
var tx0 = calcMatrix.getXRound(x, y, roundPixels);
var ty0 = calcMatrix.getYRound(x, y, roundPixels);
var tx1 = calcMatrix.getXRound(x, yh, roundPixels);
var ty1 = calcMatrix.getYRound(x, yh, roundPixels);
var tx2 = calcMatrix.getXRound(xw, yh, roundPixels);
var ty2 = calcMatrix.getYRound(xw, yh, roundPixels);
var tx3 = calcMatrix.getXRound(xw, y, roundPixels);
var ty3 = calcMatrix.getYRound(xw, y, roundPixels);
pipeline.batchQuad(tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, glyph.u0, glyph.v0, glyph.u1, glyph.v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit);
};
module.exports = BatchChar;

View file

@ -5,10 +5,10 @@
*/
/**
* Calculate the position, width and height of a BitmapText Game Object.
* Calculate the full bounds, in local and world space, of a BitmapText Game Object.
*
* Returns a BitmapTextSize object that contains global and local variants of the Game Objects x and y coordinates and
* its width and height.
* its width and height. Also includes an array of the line lengths and all word positions.
*
* The global position and size take into account the Game Object's position and scale.
*
@ -18,14 +18,17 @@
* @since 3.0.0
* @private
*
* @param {(Phaser.GameObjects.DynamicBitmapText|Phaser.GameObjects.BitmapText)} src - The BitmapText to calculate the position, width and height of.
* @param {boolean} [round] - Whether to round the results to the nearest integer.
* @param {object} [out] - Optional object to store the results in, to save constant object creation.
* @param {(Phaser.GameObjects.DynamicBitmapText|Phaser.GameObjects.BitmapText)} src - The BitmapText to calculate the bounds values for.
* @param {boolean} [round=false] - Whether to round the positions to the nearest integer.
* @param {boolean} [updateOrigin=false] - Whether to update the origin of the BitmapText after bounds calculations?
* @param {object} [out] - Object to store the results in, to save constant object creation. If not provided an empty object is returned.
*
* @return {Phaser.Types.GameObjects.BitmapText.BitmapTextSize} The calculated position, width and height of the BitmapText.
* @return {Phaser.Types.GameObjects.BitmapText.BitmapTextSize} The calculated bounds values of the BitmapText.
*/
var GetBitmapTextSize = function (src, round, out)
var GetBitmapTextSize = function (src, round, updateOrigin, out)
{
if (updateOrigin === undefined) { updateOrigin = false; }
if (out === undefined)
{
out = {
@ -49,6 +52,7 @@ var GetBitmapTextSize = function (src, round, out)
},
wrappedText: '',
words: [],
characters: [],
scaleX: 0,
scaleY: 0
};
@ -77,6 +81,8 @@ var GetBitmapTextSize = function (src, round, out)
var glyph = null;
var align = src._align;
var x = 0;
var y = 0;
@ -94,6 +100,7 @@ var GetBitmapTextSize = function (src, round, out)
var i;
var words = [];
var characters = [];
var current = null;
// Scan for breach of maxWidth and insert carriage-returns
@ -152,7 +159,7 @@ var GetBitmapTextSize = function (src, round, out)
h: current.h * sy,
cr: false
});
current = null;
}
}
@ -261,6 +268,8 @@ var GetBitmapTextSize = function (src, round, out)
current = null;
}
var charIndex = 0;
for (i = 0; i < textLength; i++)
{
charCode = text.charCodeAt(i);
@ -343,6 +352,8 @@ var GetBitmapTextSize = function (src, round, out)
bh = gh;
}
var charWidth = glyph.xOffset + glyph.xAdvance + ((kerningOffset !== undefined) ? kerningOffset : 0);
if (charCode === wordWrapCharCode)
{
if (current !== null)
@ -355,7 +366,7 @@ var GetBitmapTextSize = function (src, round, out)
w: current.w * sx,
h: current.h * sy
});
current = null;
}
}
@ -364,17 +375,33 @@ var GetBitmapTextSize = function (src, round, out)
if (current === null)
{
// We're starting a new word, recording the starting index, etc
current = { word: '', i: i, x: xAdvance, y: yAdvance, w: 0, h: lineHeight };
current = { word: '', i: charIndex, x: xAdvance, y: yAdvance, w: 0, h: lineHeight };
}
current.word = current.word.concat(text[i]);
current.w += glyph.xOffset + glyph.xAdvance + ((kerningOffset !== undefined) ? kerningOffset : 0);
current.w += charWidth;
}
characters.push({
i: charIndex,
char: text[i],
code: charCode,
x: (glyph.xOffset + xAdvance) * scale,
y: (glyph.yOffset + yAdvance) * scale,
w: glyph.width * scale,
h: glyph.height * scale,
t: yAdvance * scale,
r: gw * scale,
b: lineHeight * scale,
line: currentLine,
glyph: glyph
});
xAdvance += glyph.xAdvance + letterSpacing;
lastGlyph = glyph;
lastCharCode = charCode;
currentLineWidth = gw * scale;
charIndex++;
}
// Last word
@ -402,6 +429,30 @@ var GetBitmapTextSize = function (src, round, out)
shortestLine = currentLineWidth;
}
// Adjust all of the character positions based on alignment
if (align > 0)
{
for (var c = 0; c < characters.length; c++)
{
var currentChar = characters[c];
if (align === 1)
{
var ax1 = ((longestLine - lineWidths[currentChar.line]) / 2);
currentChar.x += ax1;
currentChar.r += ax1;
}
else if (align === 2)
{
var ax2 = (longestLine - lineWidths[currentChar.line]);
currentChar.x += ax2;
currentChar.r += ax2;
}
}
}
var local = out.local;
var global = out.global;
var lines = out.lines;
@ -411,8 +462,9 @@ var GetBitmapTextSize = function (src, round, out)
local.width = bw * scale;
local.height = bh * scale;
global.x = (src.x - src.displayOriginX) + (bx * sx);
global.y = (src.y - src.displayOriginY) + (by * sy);
global.x = (src.x - src._displayOriginX) + (bx * sx);
global.y = (src.y - src._displayOriginY) + (by * sy);
global.width = bw * sx;
global.height = bh * sy;
@ -422,22 +474,39 @@ var GetBitmapTextSize = function (src, round, out)
if (round)
{
local.x = Math.round(local.x);
local.y = Math.round(local.y);
local.width = Math.round(local.width);
local.height = Math.round(local.height);
local.x = Math.ceil(local.x);
local.y = Math.ceil(local.y);
local.width = Math.ceil(local.width);
local.height = Math.ceil(local.height);
global.x = Math.round(global.x);
global.y = Math.round(global.y);
global.width = Math.round(global.width);
global.height = Math.round(global.height);
global.x = Math.ceil(global.x);
global.y = Math.ceil(global.y);
global.width = Math.ceil(global.width);
global.height = Math.ceil(global.height);
lines.shortest = Math.round(shortestLine);
lines.longest = Math.round(longestLine);
lines.shortest = Math.ceil(shortestLine);
lines.longest = Math.ceil(longestLine);
}
if (updateOrigin)
{
src._displayOriginX = (src.originX * local.width);
src._displayOriginY = (src.originY * local.height);
global.x = src.x - (src._displayOriginX * src.scaleX);
global.y = src.y - (src._displayOriginY * src.scaleY);
if (round)
{
global.x = Math.ceil(global.x);
global.y = Math.ceil(global.y);
}
}
out.words = words;
out.characters = characters;
out.lines.height = lineHeight;
out.scale = scale;
out.scaleX = src.scaleX;
out.scaleY = src.scaleY;

View file

@ -27,12 +27,13 @@ var ParseXMLBitmapFont = require('./ParseXMLBitmapFont');
*/
var ParseFromAtlas = function (scene, fontName, textureKey, frameKey, xmlKey, xSpacing, ySpacing)
{
var frame = scene.sys.textures.getFrame(textureKey, frameKey);
var texture = scene.sys.textures.get(textureKey);
var frame = texture.get(frameKey);
var xml = scene.sys.cache.xml.get(xmlKey);
if (frame && xml)
{
var data = ParseXMLBitmapFont(xml, xSpacing, ySpacing, frame);
var data = ParseXMLBitmapFont(xml, frame, xSpacing, ySpacing, texture);
scene.sys.cache.bitmapFont.add(fontName, { data: data, texture: textureKey, frame: frameKey });

View file

@ -29,17 +29,24 @@ function getValue (node, attribute)
* @private
*
* @param {XMLDocument} xml - The XML Document to parse the font from.
* @param {Phaser.Textures.Frame} frame - The texture frame to take into account when creating the uv data.
* @param {integer} [xSpacing=0] - The x-axis spacing to add between each letter.
* @param {integer} [ySpacing=0] - The y-axis spacing to add to the line height.
* @param {Phaser.Textures.Frame} [frame] - The texture frame to take into account while parsing.
* @param {Phaser.Textures.Texture} [texture] - If provided, each glyph in the Bitmap Font will be added to this texture as a frame.
*
* @return {Phaser.Types.GameObjects.BitmapText.BitmapFontData} The parsed Bitmap Font data.
*/
var ParseXMLBitmapFont = function (xml, xSpacing, ySpacing, frame)
var ParseXMLBitmapFont = function (xml, frame, xSpacing, ySpacing, texture)
{
if (xSpacing === undefined) { xSpacing = 0; }
if (ySpacing === undefined) { ySpacing = 0; }
var textureX = frame.cutX;
var textureY = frame.cutY;
var textureWidth = frame.source.width;
var textureHeight = frame.source.height;
var sourceIndex = frame.sourceIndex;
var data = {};
var info = xml.getElementsByTagName('info')[0];
var common = xml.getElementsByTagName('common')[0];
@ -64,6 +71,7 @@ var ParseXMLBitmapFont = function (xml, xSpacing, ySpacing, frame)
var node = letters[i];
var charCode = getValue(node, 'id');
var letter = String.fromCharCode(charCode);
var gx = getValue(node, 'x');
var gy = getValue(node, 'y');
var gw = getValue(node, 'width');
@ -84,6 +92,20 @@ var ParseXMLBitmapFont = function (xml, xSpacing, ySpacing, frame)
}
}
if (adjustForTrim && top !== 0 && left !== 0)
{
// Now we know the top and left coordinates of the glyphs in the original data
// so we can work out how much to adjust the glyphs by
gx -= frame.x;
gy -= frame.y;
}
var u0 = (textureX + gx) / textureWidth;
var v0 = (textureY + gy) / textureHeight;
var u1 = (textureX + gx + gw) / textureWidth;
var v1 = (textureY + gy + gh) / textureHeight;
data.chars[charCode] =
{
x: gx,
@ -96,21 +118,21 @@ var ParseXMLBitmapFont = function (xml, xSpacing, ySpacing, frame)
yOffset: getValue(node, 'yoffset'),
xAdvance: getValue(node, 'xadvance') + xSpacing,
data: {},
kerning: {}
kerning: {},
u0: u0,
v0: v0,
u1: u1,
v1: v1
};
}
if (adjustForTrim && top !== 0 && left !== 0)
{
// Now we know the top and left coordinates of the glyphs in the original data
// so we can work out how much to adjust the glyphs by
for (var code in data.chars)
if (texture && gw !== 0 && gh !== 0)
{
var glyph = data.chars[code];
var charFrame = texture.add(letter, sourceIndex, gx, gy, gw, gh);
glyph.x -= frame.x;
glyph.y -= frame.y;
if (charFrame)
{
charFrame.setUVs(gw, gh, u0, v0, u1, v1);
}
}
}

View file

@ -5,6 +5,7 @@
*/
var Utils = require('../../../renderer/webgl/Utils');
var GetColorFromValue = require('../../../display/color/GetColorFromValue');
/**
* Renders this Game Object with the WebGL Renderer to the given Camera.
@ -35,20 +36,6 @@ var DynamicBitmapTextWebGLRenderer = function (renderer, src, interpolationPerce
renderer.setPipeline(pipeline, src);
var crop = (src.cropWidth > 0 || src.cropHeight > 0);
if (crop)
{
pipeline.flush();
renderer.pushScissor(
src.x,
src.y,
src.cropWidth * src.scaleX,
src.cropHeight * src.scaleY
);
}
var camMatrix = pipeline._tempMatrix1;
var spriteMatrix = pipeline._tempMatrix2;
var calcMatrix = pipeline._tempMatrix3;
@ -79,6 +66,20 @@ var DynamicBitmapTextWebGLRenderer = function (renderer, src, interpolationPerce
camMatrix.multiply(spriteMatrix, calcMatrix);
}
var crop = (src.cropWidth > 0 || src.cropHeight > 0);
if (crop)
{
pipeline.flush();
renderer.pushScissor(
calcMatrix.tx,
calcMatrix.ty,
src.cropWidth * calcMatrix.scaleX,
src.cropHeight * calcMatrix.scaleY
);
}
var frame = src.frame;
var texture = frame.glTexture;
var textureX = frame.cutX;
@ -92,7 +93,7 @@ var DynamicBitmapTextWebGLRenderer = function (renderer, src, interpolationPerce
var tintBL = Utils.getTintAppendFloatAlpha(src._tintBL, camera.alpha * src._alphaBL);
var tintBR = Utils.getTintAppendFloatAlpha(src._tintBR, camera.alpha * src._alphaBR);
pipeline.setTexture2D(texture, 0);
var textureUnit = pipeline.setGameObject(src);
var xAdvance = 0;
var yAdvance = 0;
@ -233,10 +234,10 @@ var DynamicBitmapTextWebGLRenderer = function (renderer, src, interpolationPerce
tintBR = output.tint.bottomRight;
}
tintTL = Utils.getTintAppendFloatAlpha(tintTL, camera.alpha * src._alphaTL);
tintTR = Utils.getTintAppendFloatAlpha(tintTR, camera.alpha * src._alphaTR);
tintBL = Utils.getTintAppendFloatAlpha(tintBL, camera.alpha * src._alphaBL);
tintBR = Utils.getTintAppendFloatAlpha(tintBR, camera.alpha * src._alphaBR);
tintTL = Utils.getTintAppendFloatAlpha(GetColorFromValue(tintTL), camera.alpha * src._alphaTL);
tintTR = Utils.getTintAppendFloatAlpha(GetColorFromValue(tintTR), camera.alpha * src._alphaTR);
tintBL = Utils.getTintAppendFloatAlpha(GetColorFromValue(tintBL), camera.alpha * src._alphaBL);
tintBR = Utils.getTintAppendFloatAlpha(GetColorFromValue(tintBR), camera.alpha * src._alphaBR);
}
x *= scale;
@ -286,7 +287,7 @@ var DynamicBitmapTextWebGLRenderer = function (renderer, src, interpolationPerce
ty3 = Math.round(ty3);
}
pipeline.batchQuad(tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, 0);
pipeline.batchQuad(tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit);
}
if (crop)

View file

@ -5,11 +5,14 @@
*/
var Class = require('../../../utils/Class');
var Clamp = require('../../../math/Clamp');
var Components = require('../../components');
var GameObject = require('../../GameObject');
var GetColorFromValue = require('../../../display/color/GetColorFromValue');
var GetBitmapTextSize = require('../GetBitmapTextSize');
var ParseFromAtlas = require('../ParseFromAtlas');
var ParseXMLBitmapFont = require('../ParseXMLBitmapFont');
var Rectangle = require('../../../geom/rectangle/Rectangle');
var Render = require('./BitmapTextRender');
/**
@ -101,6 +104,11 @@ var BitmapText = new Class({
var entry = this.scene.sys.cache.bitmapFont.get(font);
if (!entry)
{
console.warn('Invalid BitmapText key: ' + font);
}
/**
* The data of the Bitmap Font used by this Bitmap Text.
*
@ -203,6 +211,69 @@ var BitmapText = new Class({
*/
this.wordWrapCharCode = 32;
/**
* Internal array holding the character tint color data.
*
* @name Phaser.GameObjects.BitmapText#charColors
* @type {array}
* @private
* @since 3.50.0
*/
this.charColors = [];
/**
* The horizontal offset of the drop shadow.
*
* You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`.
*
* @name Phaser.GameObjects.BitmapText#dropShadowX
* @type {number}
* @since 3.50.0
*/
this.dropShadowX = 0;
/**
* The vertical offset of the drop shadow.
*
* You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`.
*
* @name Phaser.GameObjects.BitmapText#dropShadowY
* @type {number}
* @since 3.50.0
*/
this.dropShadowY = 0;
/**
* The color of the drop shadow.
*
* @name Phaser.GameObjects.BitmapText#_dropShadowColor
* @type {number}
* @private
* @since 3.50.0
*/
this._dropShadowColor = 0x000000;
/**
* The GL encoded color of the drop shadow.
*
* @name Phaser.GameObjects.BitmapText#_dropShadowColorGL
* @type {number}
* @private
* @since 3.50.0
*/
this._dropShadowColorGL = 0x000000;
/**
* The alpha value of the drop shadow.
*
* You can set this directly, or use `Phaser.GameObjects.BitmapText#setDropShadow`.
*
* @name Phaser.GameObjects.BitmapText#dropShadowAlpha
* @type {number}
* @since 3.50.0
*/
this.dropShadowAlpha = 0.5;
this.setTexture(entry.texture, entry.frame);
this.setPosition(x, y);
this.setOrigin(0, 0);
@ -343,6 +414,230 @@ var BitmapText = new Class({
return this;
},
/**
* Sets a drop shadow effect on this Bitmap Text.
*
* This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic.
*
* You can set the vertical and horizontal offset of the shadow, as well as the color and alpha.
*
* Once a shadow has been enabled you can modify the `dropShadowX` and `dropShadowY` properties of this
* Bitmap Text directly to adjust the position of the shadow in real-time.
*
* If you wish to clear the shadow, call this method with no parameters specified.
*
* @method Phaser.GameObjects.BitmapText#setDropShadow
* @webglOnly
* @since 3.50.0
*
* @param {number} [x=0] - The horizontal offset of the drop shadow.
* @param {number} [y=0] - The vertical offset of the drop shadow.
* @param {number} [color=0xffffff] - The color of the drop shadow, given as a hex value, i.e. `0x000000` for black.
* @param {number} [alpha=0.5] - The alpha of the drop shadow, given as a float between 0 and 1. This is combined with the Bitmap Text alpha as well.
*
* @return {this} This BitmapText Object.
*/
setDropShadow: function (x, y, color, alpha)
{
if (x === undefined) { x = 0; }
if (y === undefined) { y = 0; }
if (color === undefined) { color = 0x000000; }
if (alpha === undefined) { alpha = 0.5; }
this.dropShadowX = x;
this.dropShadowY = y;
this.dropShadowAlpha = alpha;
this.dropShadowColor = color;
return this;
},
/**
* Sets a tint on a range of characters in this Bitmap Text, starting from the `start` parameter index
* and running for `length` quantity of characters.
*
* The `start` parameter can be negative. In this case, it starts at the end of the text and counts
* backwards `start` places.
*
* You can also pass in -1 as the `length` and it will tint all characters from `start`
* up until the end of the string.
* Remember that spaces and punctuation count as characters.
*
* This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic.
*
* The tint works by taking the pixel color values from the Bitmap Text texture, and then
* multiplying it by the color value of the tint. You can provide either one color value,
* in which case the whole character will be tinted in that color. Or you can provide a color
* per corner. The colors are blended together across the extent of the character range.
*
* To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`.
*
* To modify the tint color once set, call this method again with new color values.
*
* Using `setWordTint` can override tints set by this function, and vice versa.
*
* To remove a tint call this method with just the `start`, and optionally, the `length` parameters defined.
*
* @method Phaser.GameObjects.BitmapText#setCharacterTint
* @webglOnly
* @since 3.50.0
*
* @param {number} [start=0] - The starting character to begin the tint at. If negative, it counts back from the end of the text.
* @param {number} [length=1] - The number of characters to tint. Remember that spaces count as a character too. Pass -1 to tint all characters from `start` onwards.
* @param {boolean} [tintFill=false] - Use a fill-based tint (true), or an additive tint (false)
* @param {integer} [topLeft=0xffffff] - The tint being applied to the top-left of the character. If not other values are given this value is applied evenly, tinting the whole character.
* @param {integer} [topRight] - The tint being applied to the top-right of the character.
* @param {integer} [bottomLeft] - The tint being applied to the bottom-left of the character.
* @param {integer} [bottomRight] - The tint being applied to the bottom-right of the character.
*
* @return {this} This BitmapText Object.
*/
setCharacterTint: function (start, length, tintFill, topLeft, topRight, bottomLeft, bottomRight)
{
if (start === undefined) { start = 0; }
if (length === undefined) { length = 1; }
if (tintFill === undefined) { tintFill = false; }
if (topLeft === undefined) { topLeft = -1; }
if (topRight === undefined)
{
topRight = topLeft;
bottomLeft = topLeft;
bottomRight = topLeft;
}
var len = this.text.length;
if (length === -1)
{
length = len;
}
if (start < 0)
{
start = len + start;
}
start = Clamp(start, 0, len - 1);
var end = Clamp(start + length, start, len);
var charColors = this.charColors;
for (var i = start; i < end; i++)
{
var color = charColors[i];
if (topLeft === -1)
{
charColors[i] = null;
}
else
{
var tintEffect = (tintFill) ? 1 : 0;
var tintTL = GetColorFromValue(topLeft);
var tintTR = GetColorFromValue(topRight);
var tintBL = GetColorFromValue(bottomLeft);
var tintBR = GetColorFromValue(bottomRight);
if (color)
{
color.tintEffect = tintEffect;
color.tintTL = tintTL;
color.tintTR = tintTR;
color.tintBL = tintBL;
color.tintBR = tintBR;
}
else
{
charColors[i] = {
tintEffect: tintEffect,
tintTL: tintTL,
tintTR: tintTR,
tintBL: tintBL,
tintBR: tintBR
};
}
}
}
return this;
},
/**
* Sets a tint on a matching word within this Bitmap Text.
*
* The `word` parameter can be either a string or a number.
*
* If a string, it will run a string comparison against the text contents, and if matching,
* it will tint the whole word.
*
* If a number, if till that word, based on its offset within the text contents.
*
* The `count` parameter controls how many words are replaced. Pass in -1 to replace them all.
*
* This parameter is ignored if you pass a number as the `word` to be searched for.
*
* This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic.
*
* The tint works by taking the pixel color values from the Bitmap Text texture, and then
* multiplying it by the color value of the tint. You can provide either one color value,
* in which case the whole character will be tinted in that color. Or you can provide a color
* per corner. The colors are blended together across the extent of the character range.
*
* To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`.
*
* To modify the tint color once set, call this method again with new color values.
*
* Using `setCharacterTint` can override tints set by this function, and vice versa.
*
* @method Phaser.GameObjects.BitmapText#setWordTint
* @webglOnly
* @since 3.50.0
*
* @param {(string|number)} word - The word to search for. Either a string, or an index of the word in the words array.
* @param {number} [count=1] - The number of matching words to tint. Pass -1 to tint all matching words.
* @param {boolean} [tintFill=false] - Use a fill-based tint (true), or an additive tint (false)
* @param {integer} [topLeft=0xffffff] - The tint being applied to the top-left of the word. If not other values are given this value is applied evenly, tinting the whole word.
* @param {integer} [topRight] - The tint being applied to the top-right of the word.
* @param {integer} [bottomLeft] - The tint being applied to the bottom-left of the word.
* @param {integer} [bottomRight] - The tint being applied to the bottom-right of the word.
*
* @return {this} This BitmapText Object.
*/
setWordTint: function (word, count, tintFill, topLeft, topRight, bottomLeft, bottomRight)
{
if (count === undefined) { count = 1; }
var bounds = this.getTextBounds();
var words = bounds.words;
var wordIsNumber = (typeof(word) === 'number');
var total = 0;
for (var i = 0; i < words.length; i++)
{
var lineword = words[i];
if ((wordIsNumber && i === word) || (!wordIsNumber && lineword.word === word))
{
this.setCharacterTint(lineword.i, lineword.word.length, tintFill, topLeft, topRight, bottomLeft, bottomRight);
total++;
if (total === count)
{
return this;
}
}
}
return this;
},
/**
* Calculate the bounds of this Bitmap Text.
*
@ -358,7 +653,7 @@ var BitmapText = new Class({
* @method Phaser.GameObjects.BitmapText#getTextBounds
* @since 3.0.0
*
* @param {boolean} [round] - Whether to round the results to the nearest integer.
* @param {boolean} [round=false] - Whether to round the results up to the nearest integer.
*
* @return {Phaser.Types.GameObjects.BitmapText.BitmapTextSize} An object that describes the size of this Bitmap Text.
*/
@ -370,18 +665,83 @@ var BitmapText = new Class({
var bounds = this._bounds;
if (this._dirty || this.scaleX !== bounds.scaleX || this.scaleY !== bounds.scaleY)
if (this._dirty || round || this.scaleX !== bounds.scaleX || this.scaleY !== bounds.scaleY)
{
GetBitmapTextSize(this, round, bounds);
GetBitmapTextSize(this, round, true, bounds);
this._dirty = false;
this.updateDisplayOrigin();
}
return bounds;
},
/**
* Gets the character located at the given x/y coordinate within this Bitmap Text.
*
* The coordinates you pass in are translated into the local space of the
* Bitmap Text, however, it is up to you to first translate the input coordinates to world space.
*
* If you wish to use this in combination with an input event, be sure
* to pass in `Pointer.worldX` and `worldY` so they are in world space.
*
* In some cases, based on kerning, characters can overlap. When this happens,
* the first character in the word is returned.
*
* Note that this does not work for DynamicBitmapText if you have changed the
* character positions during render. It will only scan characters in their un-translated state.
*
* @method Phaser.GameObjects.BitmapText#getCharacterAt
* @since 3.50.0
*
* @param {number} x - The x position to check.
* @param {number} y - The y position to check.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera which is being tested against. If not given will use the Scene default camera.
*
* @return {Phaser.Types.GameObjects.BitmapText.BitmapTextCharacter} The character object at the given position, or `null`.
*/
getCharacterAt: function (x, y, camera)
{
var point = this.getLocalPoint(x, y, null, camera);
var bounds = this.getTextBounds();
var chars = bounds.characters;
var tempRect = new Rectangle();
for (var i = 0; i < chars.length; i++)
{
var char = chars[i];
tempRect.setTo(char.x, char.t, char.r - char.x, char.b);
if (tempRect.contains(point.x, point.y))
{
return char;
}
}
return null;
},
/**
* Updates the Display Origin cached values internally stored on this Game Object.
* You don't usually call this directly, but it is exposed for edge-cases where you may.
*
* @method Phaser.GameObjects.BitmapText#updateDisplayOrigin
* @since 3.0.0
*
* @return {this} This Game Object instance.
*/
updateDisplayOrigin: function ()
{
this._dirty = true;
this.getTextBounds(false);
return this;
},
/**
* Changes the font this BitmapText is using to render.
*
@ -415,7 +775,7 @@ var BitmapText = new Class({
this.setTexture(entry.texture, entry.frame);
GetBitmapTextSize(this, false, this._bounds);
GetBitmapTextSize(this, false, true, this._bounds);
}
}
@ -629,6 +989,31 @@ var BitmapText = new Class({
},
/**
* The color of the drop shadow.
*
* You can also set this via `Phaser.GameObjects.BitmapText#setDropShadow`.
*
* @name Phaser.GameObjects.BitmapText#dropShadowColor
* @type {number}
* @since 3.50.0
*/
dropShadowColor: {
get: function ()
{
return this._dropShadowColor;
},
set: function (value)
{
this._dropShadowColor = value;
this._dropShadowColorGL = GetColorFromValue(value);
}
},
/**
* Build a JSON representation of this Bitmap Text.
*
@ -654,6 +1039,20 @@ var BitmapText = new Class({
out.data = data;
return out;
},
/**
* Internal destroy handler, called as part of the destroy process.
*
* @method Phaser.GameObjects.BitmapText#preDestroy
* @protected
* @since 3.50.0
*/
preDestroy: function ()
{
this.charColors.length = 0;
this._bounds = null;
this.fontData = null;
}
});
@ -712,9 +1111,9 @@ BitmapText.ParseFromAtlas = ParseFromAtlas;
* @since 3.17.0
*
* @param {XMLDocument} xml - The XML Document to parse the font from.
* @param {Phaser.Textures.Frame} frame - The texture frame to take into account when creating the uv data.
* @param {integer} [xSpacing=0] - The x-axis spacing to add between each letter.
* @param {integer} [ySpacing=0] - The y-axis spacing to add to the line height.
* @param {Phaser.Textures.Frame} [frame] - The texture frame to take into account while parsing.
*
* @return {Phaser.Types.GameObjects.BitmapText.BitmapFontData} The parsed Bitmap Font data.
*/

View file

@ -4,6 +4,7 @@
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var BatchChar = require('../BatchChar');
var Utils = require('../../../renderer/webgl/Utils');
/**
@ -30,7 +31,7 @@ var BitmapTextWebGLRenderer = function (renderer, src, interpolationPercentage,
{
return;
}
var pipeline = this.pipeline;
renderer.setPipeline(pipeline, src);
@ -64,166 +65,89 @@ var BitmapTextWebGLRenderer = function (renderer, src, interpolationPercentage,
camMatrix.multiply(spriteMatrix, calcMatrix);
}
var frame = src.frame;
var texture = frame.glTexture;
var textureX = frame.cutX;
var textureY = frame.cutY;
var textureWidth = texture.width;
var textureHeight = texture.height;
var roundPixels = camera.roundPixels;
var cameraAlpha = camera.alpha;
var charColors = src.charColors;
var tintEffect = (src._isTinted && src.tintFill);
var tintTL = Utils.getTintAppendFloatAlpha(src._tintTL, camera.alpha * src._alphaTL);
var tintTR = Utils.getTintAppendFloatAlpha(src._tintTR, camera.alpha * src._alphaTR);
var tintBL = Utils.getTintAppendFloatAlpha(src._tintBL, camera.alpha * src._alphaBL);
var tintBR = Utils.getTintAppendFloatAlpha(src._tintBR, camera.alpha * src._alphaBR);
pipeline.setTexture2D(texture, 0);
var tintTL = Utils.getTintAppendFloatAlpha(src._tintTL, cameraAlpha * src._alphaTL);
var tintTR = Utils.getTintAppendFloatAlpha(src._tintTR, cameraAlpha * src._alphaTR);
var tintBL = Utils.getTintAppendFloatAlpha(src._tintBL, cameraAlpha * src._alphaBL);
var tintBR = Utils.getTintAppendFloatAlpha(src._tintBR, cameraAlpha * src._alphaBR);
var xAdvance = 0;
var yAdvance = 0;
var charCode = 0;
var lastCharCode = 0;
var letterSpacing = src._letterSpacing;
var glyph;
var glyphX = 0;
var glyphY = 0;
var glyphW = 0;
var glyphH = 0;
var lastGlyph;
var fontData = src.fontData;
var chars = fontData.chars;
var lineHeight = fontData.lineHeight;
var scale = (src._fontSize / fontData.size);
var align = src._align;
var currentLine = 0;
var lineOffsetX = 0;
var texture = src.frame.glTexture;
var textureUnit = pipeline.setGameObject(src);
// Update the bounds - skipped internally if not dirty
var bounds = src.getTextBounds(false);
// In case the method above changed it (word wrapping)
if (src.maxWidth > 0)
var i;
var char;
var glyph;
var characters = bounds.characters;
var dropShadowX = src.dropShadowX;
var dropShadowY = src.dropShadowY;
var dropShadow = (dropShadowX !== 0 || dropShadowY !== 0);
if (dropShadow)
{
text = bounds.wrappedText;
textLength = text.length;
}
var srcShadowColor = src._dropShadowColorGL;
var srcShadowAlpha = src.dropShadowAlpha;
var lineData = src._bounds.lines;
var blackTL = Utils.getTintAppendFloatAlpha(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaTL);
var blackTR = Utils.getTintAppendFloatAlpha(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaTR);
var blackBL = Utils.getTintAppendFloatAlpha(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaBL);
var blackBR = Utils.getTintAppendFloatAlpha(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaBR);
if (align === 1)
{
lineOffsetX = (lineData.longest - lineData.lengths[0]) / 2;
}
else if (align === 2)
{
lineOffsetX = (lineData.longest - lineData.lengths[0]);
}
var roundPixels = camera.roundPixels;
for (var i = 0; i < textLength; i++)
{
charCode = text.charCodeAt(i);
// Carriage-return
if (charCode === 10)
for (i = 0; i < characters.length; i++)
{
currentLine++;
char = characters[i];
glyph = char.glyph;
if (align === 1)
if (char.code === 32 || glyph.width === 0 || glyph.height === 0)
{
lineOffsetX = (lineData.longest - lineData.lengths[currentLine]) / 2;
continue;
}
else if (align === 2)
{
lineOffsetX = (lineData.longest - lineData.lengths[currentLine]);
}
xAdvance = 0;
yAdvance += lineHeight;
lastGlyph = null;
continue;
BatchChar(pipeline, src, char, glyph, dropShadowX, dropShadowY, calcMatrix, roundPixels, blackTL, blackTR, blackBL, blackBR, 0, texture, textureUnit);
}
}
glyph = chars[charCode];
for (i = 0; i < characters.length; i++)
{
char = characters[i];
glyph = char.glyph;
if (!glyph)
if (char.code === 32 || glyph.width === 0 || glyph.height === 0)
{
continue;
}
glyphX = textureX + glyph.x;
glyphY = textureY + glyph.y;
glyphW = glyph.width;
glyphH = glyph.height;
var x = glyph.xOffset + xAdvance;
var y = glyph.yOffset + yAdvance;
if (lastGlyph !== null)
if (charColors[char.i])
{
var kerningOffset = glyph.kerning[lastCharCode];
x += (kerningOffset !== undefined) ? kerningOffset : 0;
var color = charColors[char.i];
var ctintEffect = color.tintEffect;
var ctintTL = Utils.getTintAppendFloatAlpha(color.tintTL, cameraAlpha * src._alphaTL);
var ctintTR = Utils.getTintAppendFloatAlpha(color.tintTR, cameraAlpha * src._alphaTR);
var ctintBL = Utils.getTintAppendFloatAlpha(color.tintBL, cameraAlpha * src._alphaBL);
var ctintBR = Utils.getTintAppendFloatAlpha(color.tintBR, cameraAlpha * src._alphaBR);
BatchChar(pipeline, src, char, glyph, 0, 0, calcMatrix, roundPixels, ctintTL, ctintTR, ctintBL, ctintBR, ctintEffect, texture, textureUnit);
}
else
{
BatchChar(pipeline, src, char, glyph, 0, 0, calcMatrix, roundPixels, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit);
}
xAdvance += glyph.xAdvance + letterSpacing;
lastGlyph = glyph;
lastCharCode = charCode;
// Nothing to render or a space? Then skip to the next glyph
if (glyphW === 0 || glyphH === 0 || charCode === 32)
{
continue;
}
x *= scale;
y *= scale;
x -= src.displayOriginX;
y -= src.displayOriginY;
x += lineOffsetX;
var u0 = glyphX / textureWidth;
var v0 = glyphY / textureHeight;
var u1 = (glyphX + glyphW) / textureWidth;
var v1 = (glyphY + glyphH) / textureHeight;
var xw = x + (glyphW * scale);
var yh = y + (glyphH * scale);
var tx0 = calcMatrix.getX(x, y);
var ty0 = calcMatrix.getY(x, y);
var tx1 = calcMatrix.getX(x, yh);
var ty1 = calcMatrix.getY(x, yh);
var tx2 = calcMatrix.getX(xw, yh);
var ty2 = calcMatrix.getY(xw, yh);
var tx3 = calcMatrix.getX(xw, y);
var ty3 = calcMatrix.getY(xw, y);
if (roundPixels)
{
tx0 = Math.round(tx0);
ty0 = Math.round(ty0);
tx1 = Math.round(tx1);
ty1 = Math.round(ty1);
tx2 = Math.round(tx2);
ty2 = Math.round(ty2);
tx3 = Math.round(tx3);
ty3 = Math.round(ty3);
}
pipeline.batchQuad(tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, 0);
// Debug test if the characters are in the correct place when rendered:
// pipeline.drawFillRect(tx0, ty0, tx2 - tx0, ty2 - ty0, 0x00ff00, 0.5);
}
};

View file

@ -3,6 +3,8 @@
*
* Describes the character's position, size, offset and kerning.
*
* As of version 3.50 it also includes the WebGL texture uv data.
*
* @typedef {object} Phaser.Types.GameObjects.BitmapText.BitmapFontCharacterData
* @since 3.0.0
*
@ -14,6 +16,10 @@
* @property {number} centerY - The center y position of the character.
* @property {number} xOffset - The x offset of the character.
* @property {number} yOffset - The y offset of the character.
* @property {number} u0 - WebGL texture u0.
* @property {number} v0 - WebGL texture v0.
* @property {number} u1 - WebGL texture u1.
* @property {number} v1 - WebGL texture v1.
* @property {object} data - Extra data for the character.
* @property {Object.<number>} kerning - Kerning values, keyed by character code.
*/

View file

@ -0,0 +1,22 @@
/**
* A single entry from the `BitmapTextSize` characters array.
*
* The position and dimensions take the font size into account,
* but are not translated into the local space of the Game Object itself.
*
* @typedef {object} Phaser.Types.GameObjects.BitmapText.BitmapTextCharacter
* @since 3.50.0
*
* @property {number} i - The index of this character within the BitmapText text string.
* @property {string} char - The character.
* @property {number} code - The character code of the character.
* @property {number} x - The x position of the character in the BitmapText.
* @property {number} y - The y position of the character in the BitmapText.
* @property {number} w - The width of the character.
* @property {number} h - The height of the character.
* @property {number} t - The top of the line this character is on.
* @property {number} r - The right-most point of this character, including xAdvance.
* @property {number} b - The bottom of the line this character is on.
* @property {number} line - The line number the character appears on.
* @property {Phaser.Types.GameObjects.BitmapText.BitmapFontCharacterData} glyph - Reference to the glyph object this character is using.
*/

View file

@ -0,0 +1,11 @@
/**
* Details about the line data in the `BitmapTextSize` object.
*
* @typedef {object} Phaser.Types.GameObjects.BitmapText.BitmapTextLines
* @since 3.50.0
*
* @property {number} shortest - The width of the shortest line of text.
* @property {number} longest - The width of the longest line of text.
* @property {number} height - The height of a line of text.
* @property {number[]} lengths - An array where each entry contains the length of that line of text.
*/

View file

@ -4,4 +4,11 @@
*
* @property {Phaser.Types.GameObjects.BitmapText.GlobalBitmapTextSize} global - The position and size of the BitmapText, taking into account the position and scale of the Game Object.
* @property {Phaser.Types.GameObjects.BitmapText.LocalBitmapTextSize} local - The position and size of the BitmapText, taking just the font size into account.
* @property {Phaser.Types.GameObjects.BitmapText.BitmapTextLines} lines - Data about the lines of text within the BitmapText.
* @property {Phaser.Types.GameObjects.BitmapText.BitmapTextCharacter[]} characters - An array containing per-character data. Only populated if `includeChars` is `true` in the `getTextBounds` call.
* @property {Phaser.Types.GameObjects.BitmapText.BitmapTextWord[]} words - An array containing the word data from the BitmapText.
* @property {number} scale - The scale of the BitmapText font being rendered vs. font size in the text data.
* @property {number} scaleX - The scale X value of the BitmapText.
* @property {number} scaleY - The scale Y value of the BitmapText.
* @property {string} wrappedText - The wrapped text, if wrapping enabled and required.
*/

View file

@ -0,0 +1,13 @@
/**
* Details about a single world entry in the `BitmapTextSize` object words array.
*
* @typedef {object} Phaser.Types.GameObjects.BitmapText.BitmapTextWord
* @since 3.50.0
*
* @property {number} x - The x position of the word in the BitmapText.
* @property {number} y - The y position of the word in the BitmapText.
* @property {number} w - The width of the word.
* @property {number} h - The height of the word.
* @property {number} i - The index of the word within the line.
* @property {string} word - The word.
*/

View file

@ -99,7 +99,7 @@ var BlitterWebGLRenderer = function (renderer, src, interpolationPercentage, cam
// Bind texture only if the Texture Source is different from before
if (frame.sourceIndex !== prevTextureSourceIndex)
{
pipeline.setTexture2D(frame.glTexture, 0);
var textureUnit = pipeline.setGameObject(src, frame);
prevTextureSourceIndex = frame.sourceIndex;
}
@ -114,7 +114,7 @@ var BlitterWebGLRenderer = function (renderer, src, interpolationPercentage, cam
}
// TL x/y, BL x/y, BR x/y, TR x/y
if (pipeline.batchQuad(tx0, ty0, tx0, ty1, tx1, ty1, tx1, ty0, frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, tintEffect, frame.glTexture, 0))
if (pipeline.batchQuad(tx0, ty0, tx0, ty1, tx1, ty1, tx1, ty0, frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, tintEffect, frame.glTexture, textureUnit))
{
prevTextureSourceIndex = -1;
}

View file

@ -87,6 +87,15 @@ var Animation = new Class({
*/
this.nextAnim = null;
/**
* A queue of keys of the next Animations to be loaded into this Animation Controller when the current animation completes.
*
* @name Phaser.GameObjects.Components.Animation#nextAnimsQueue
* @type {string[]}
* @since 3.24.0
*/
this.nextAnimsQueue = [];
/**
* Time scale factor.
*
@ -297,14 +306,14 @@ var Animation = new Class({
/**
* Sets an animation to be played immediately after the current one completes.
*
*
* The current animation must enter a 'completed' state for this to happen, i.e. finish all of its repeats, delays, etc, or have the `stop` method called directly on it.
*
*
* An animation set to repeat forever will never enter a completed state.
*
*
* You can chain a new animation at any point, including before the current one starts playing, during it, or when it ends (via its `animationcomplete` callback).
* Chained animations are specific to a Game Object, meaning different Game Objects can have different chained animations without impacting the global animation they're playing.
*
*
* Call this method with no arguments to reset the chained animation.
*
* @method Phaser.GameObjects.Components.Animation#chain
@ -321,7 +330,14 @@ var Animation = new Class({
key = key.key;
}
this.nextAnim = key;
if (this.nextAnim === null)
{
this.nextAnim = key;
}
else
{
this.nextAnimsQueue.push(key);
}
return this.parent;
},
@ -496,7 +512,7 @@ var Animation = new Class({
/**
* Plays an Animation on a Game Object that has the Animation component, such as a Sprite.
*
*
* Animations are stored in the global Animation Manager and are referenced by a unique string-based key.
*
* @method Phaser.GameObjects.Components.Animation#play
@ -570,9 +586,9 @@ var Animation = new Class({
* Load an Animation and fires 'onStartEvent' event, extracted from 'play' method.
*
* @method Phaser.GameObjects.Components.Animation#_startAnimation
* @fires Phaser.Animations.Events#START_ANIMATION_EVENT
* @fires Phaser.Animations.Events#SPRITE_START_ANIMATION_EVENT
* @fires Phaser.Animations.Events#SPRITE_START_KEY_ANIMATION_EVENT
* @fires Phaser.Animations.Events#ANIMATION_START
* @fires Phaser.Animations.Events#SPRITE_ANIMATION_START
* @fires Phaser.Animations.Events#SPRITE_ANIMATION_KEY_START
* @since 3.12.0
*
* @param {string} key - The string-based key of the animation to play, as defined previously in the Animation Manager.
@ -777,9 +793,9 @@ var Animation = new Class({
* Restarts the current animation from its beginning, optionally including its delay value.
*
* @method Phaser.GameObjects.Components.Animation#restart
* @fires Phaser.Animations.Events#RESTART_ANIMATION_EVENT
* @fires Phaser.Animations.Events#SPRITE_RESTART_ANIMATION_EVENT
* @fires Phaser.Animations.Events#SPRITE_RESTART_KEY_ANIMATION_EVENT
* @fires Phaser.Animations.Events#ANIMATION_RESTART
* @fires Phaser.Animations.Events#SPRITE_ANIMATION_RESTART
* @fires Phaser.Animations.Events#SPRITE_ANIMATION_KEY_RESTART
* @since 3.0.0
*
* @param {boolean} [includeDelay=false] - Whether to include the delay value of the animation when restarting.
@ -816,9 +832,9 @@ var Animation = new Class({
/**
* Immediately stops the current animation from playing and dispatches the `animationcomplete` event.
*
*
* If no animation is set, no event will be dispatched.
*
*
* If there is another animation queued (via the `chain` method) then it will start playing immediately.
*
* @method Phaser.GameObjects.Components.Animation#stop
@ -842,7 +858,7 @@ var Animation = new Class({
anim.emit(Events.ANIMATION_COMPLETE, anim, frame, gameObject);
gameObject.emit(Events.SPRITE_ANIMATION_KEY_COMPLETE + anim.key, anim, frame, gameObject);
gameObject.emit(Events.SPRITE_ANIMATION_COMPLETE, anim, frame, gameObject);
}
@ -850,7 +866,7 @@ var Animation = new Class({
{
var key = this.nextAnim;
this.nextAnim = null;
this.nextAnim = (this.nextAnimsQueue.length > 0) ? this.nextAnimsQueue.shift() : null;
this.play(key);
}
@ -1039,8 +1055,8 @@ var Animation = new Class({
* Internal frame change handler.
*
* @method Phaser.GameObjects.Components.Animation#updateFrame
* @fires Phaser.Animations.Events#SPRITE_ANIMATION_UPDATE_EVENT
* @fires Phaser.Animations.Events#SPRITE_ANIMATION_KEY_UPDATE_EVENT
* @fires Phaser.Animations.Events#SPRITE_ANIMATION_UPDATE
* @fires Phaser.Animations.Events#SPRITE_ANIMATION_KEY_UPDATE
* @private
* @since 3.0.0
*
@ -1073,7 +1089,7 @@ var Animation = new Class({
/**
* Advances the animation to the next frame, regardless of the time or animation state.
* If the animation is set to repeat, or yoyo, this will still take effect.
*
*
* Calling this does not change the direction of the animation. I.e. if it was currently
* playing in reverse, calling this method doesn't then change the direction to forwards.
*
@ -1095,7 +1111,7 @@ var Animation = new Class({
/**
* Advances the animation to the previous frame, regardless of the time or animation state.
* If the animation is set to repeat, or yoyo, this will still take effect.
*
*
* Calling this does not change the direction of the animation. I.e. if it was currently
* playing in forwards, calling this method doesn't then change the direction to backwards.
*
@ -1162,6 +1178,7 @@ var Animation = new Class({
this.animationManager = null;
this.parent = null;
this.nextAnimsQueue.length = 0;
this.currentAnim = null;
this.currentFrame = null;

View file

@ -31,7 +31,7 @@ var Depth = {
* The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order
* of Game Objects, without actually moving their position in the display list.
*
* The depth starts from zero (the default value) and increases from that point. A Game Object with a higher depth
* The default depth is zero. A Game Object with a higher depth
* value will always render in front of one with a lower value.
*
* Setting the depth will queue a depth sort event within the Scene.
@ -61,7 +61,7 @@ var Depth = {
* The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order
* of Game Objects, without actually moving their position in the display list.
*
* The depth starts from zero (the default value) and increases from that point. A Game Object with a higher depth
* The default depth is zero. A Game Object with a higher depth
* value will always render in front of one with a lower value.
*
* Setting the depth will queue a depth sort event within the Scene.

View file

@ -70,6 +70,15 @@ var PathFollower = {
*/
pathVector: null,
/**
* The distance the follower has traveled from the previous point to the current one, at the last update.
*
* @name Phaser.GameObjects.PathFollower#pathDelta
* @type {Phaser.Math.Vector2}
* @since 3.23.0
*/
pathDelta: null,
/**
* The Tween used for following the Path.
*
@ -235,6 +244,13 @@ var PathFollower = {
this.pathVector = new Vector2();
}
if (!this.pathDelta)
{
this.pathDelta = new Vector2();
}
this.pathDelta.reset();
this.pathTween = this.scene.sys.tweens.addCounter(config);
// The starting point of the path, relative to this follower
@ -344,14 +360,18 @@ var PathFollower = {
if (tween)
{
var tweenData = tween.data[0];
var pathDelta = this.pathDelta;
var pathVector = this.pathVector;
pathDelta.copy(pathVector).negate();
if (tweenData.state === TWEEN_CONST.COMPLETE)
{
this.path.getPoint(1, pathVector);
pathDelta.add(pathVector);
pathVector.add(this.pathOffset);
this.setPosition(pathVector.x, pathVector.y);
return;
@ -364,6 +384,7 @@ var PathFollower = {
this.path.getPoint(tween.getValue(), pathVector);
pathDelta.add(pathVector);
pathVector.add(this.pathOffset);
var oldX = this.x;

View file

@ -4,20 +4,12 @@
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
/**
* @function GetColor
* @since 3.0.0
* @private
*/
var GetColor = function (value)
{
return (value >> 16) + (value & 0xff00) + ((value & 0xff) << 16);
};
var GetColorFromValue = require('../../display/color/GetColorFromValue');
/**
* Provides methods used for setting the tint of a Game Object.
* Should be applied as a mixin and not used directly.
*
*
* @namespace Phaser.GameObjects.Components.Tint
* @webglOnly
* @since 3.0.0
@ -27,7 +19,7 @@ var Tint = {
/**
* Private internal value. Holds the top-left tint value.
*
*
* @name Phaser.GameObjects.Components.Tint#_tintTL
* @type {number}
* @private
@ -38,7 +30,7 @@ var Tint = {
/**
* Private internal value. Holds the top-right tint value.
*
*
* @name Phaser.GameObjects.Components.Tint#_tintTR
* @type {number}
* @private
@ -49,7 +41,7 @@ var Tint = {
/**
* Private internal value. Holds the bottom-left tint value.
*
*
* @name Phaser.GameObjects.Components.Tint#_tintBL
* @type {number}
* @private
@ -60,7 +52,7 @@ var Tint = {
/**
* Private internal value. Holds the bottom-right tint value.
*
*
* @name Phaser.GameObjects.Components.Tint#_tintBR
* @type {number}
* @private
@ -71,7 +63,7 @@ var Tint = {
/**
* Private internal value. Holds if the Game Object is tinted or not.
*
*
* @name Phaser.GameObjects.Components.Tint#_isTinted
* @type {boolean}
* @private
@ -82,7 +74,7 @@ var Tint = {
/**
* Fill or additive?
*
*
* @name Phaser.GameObjects.Components.Tint#tintFill
* @type {boolean}
* @default false
@ -92,14 +84,14 @@ var Tint = {
/**
* Clears all tint values associated with this Game Object.
*
*
* Immediately sets the color values back to 0xffffff and the tint type to 'additive',
* which results in no visible change to the texture.
*
* @method Phaser.GameObjects.Components.Tint#clearTint
* @webglOnly
* @since 3.0.0
*
*
* @return {this} This Game Object instance.
*/
clearTint: function ()
@ -113,18 +105,18 @@ var Tint = {
/**
* Sets an additive tint on this Game Object.
*
*
* The tint works by taking the pixel color values from the Game Objects texture, and then
* multiplying it by the color value of the tint. You can provide either one color value,
* in which case the whole Game Object will be tinted in that color. Or you can provide a color
* per corner. The colors are blended together across the extent of the Game Object.
*
*
* To modify the tint color once set, either call this method again with new values or use the
* `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight,
* `tintBottomLeft` and `tintBottomRight` to set the corner color values independently.
*
*
* To remove a tint call `clearTint`.
*
*
* To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`.
*
* @method Phaser.GameObjects.Components.Tint#setTint
@ -135,7 +127,7 @@ var Tint = {
* @param {integer} [topRight] - The tint being applied to the top-right of the Game Object.
* @param {integer} [bottomLeft] - The tint being applied to the bottom-left of the Game Object.
* @param {integer} [bottomRight] - The tint being applied to the bottom-right of the Game Object.
*
*
* @return {this} This Game Object instance.
*/
setTint: function (topLeft, topRight, bottomLeft, bottomRight)
@ -149,10 +141,10 @@ var Tint = {
bottomRight = topLeft;
}
this._tintTL = GetColor(topLeft);
this._tintTR = GetColor(topRight);
this._tintBL = GetColor(bottomLeft);
this._tintBR = GetColor(bottomRight);
this._tintTL = GetColorFromValue(topLeft);
this._tintTR = GetColorFromValue(topRight);
this._tintBL = GetColorFromValue(bottomLeft);
this._tintBR = GetColorFromValue(bottomRight);
this._isTinted = true;
@ -163,19 +155,19 @@ var Tint = {
/**
* Sets a fill-based tint on this Game Object.
*
*
* Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture
* with those in the tint. You can use this for effects such as making a player flash 'white'
* if hit by something. You can provide either one color value, in which case the whole
* Game Object will be rendered in that color. Or you can provide a color per corner. The colors
* are blended together across the extent of the Game Object.
*
*
* To modify the tint color once set, either call this method again with new values or use the
* `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight,
* `tintBottomLeft` and `tintBottomRight` to set the corner color values independently.
*
*
* To remove a tint call `clearTint`.
*
*
* To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`.
*
* @method Phaser.GameObjects.Components.Tint#setTintFill
@ -186,7 +178,7 @@ var Tint = {
* @param {integer} [topRight] - The tint being applied to the top-right of the Game Object.
* @param {integer} [bottomLeft] - The tint being applied to the bottom-left of the Game Object.
* @param {integer} [bottomRight] - The tint being applied to the bottom-right of the Game Object.
*
*
* @return {this} This Game Object instance.
*/
setTintFill: function (topLeft, topRight, bottomLeft, bottomRight)
@ -201,7 +193,7 @@ var Tint = {
/**
* The tint value being applied to the top-left of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
*
*
* @name Phaser.GameObjects.Components.Tint#tintTopLeft
* @type {integer}
* @webglOnly
@ -216,7 +208,7 @@ var Tint = {
set: function (value)
{
this._tintTL = GetColor(value);
this._tintTL = GetColorFromValue(value);
this._isTinted = true;
}
@ -225,7 +217,7 @@ var Tint = {
/**
* The tint value being applied to the top-right of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
*
*
* @name Phaser.GameObjects.Components.Tint#tintTopRight
* @type {integer}
* @webglOnly
@ -240,7 +232,7 @@ var Tint = {
set: function (value)
{
this._tintTR = GetColor(value);
this._tintTR = GetColorFromValue(value);
this._isTinted = true;
}
@ -249,7 +241,7 @@ var Tint = {
/**
* The tint value being applied to the bottom-left of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
*
*
* @name Phaser.GameObjects.Components.Tint#tintBottomLeft
* @type {integer}
* @webglOnly
@ -264,7 +256,7 @@ var Tint = {
set: function (value)
{
this._tintBL = GetColor(value);
this._tintBL = GetColorFromValue(value);
this._isTinted = true;
}
@ -273,7 +265,7 @@ var Tint = {
/**
* The tint value being applied to the bottom-right of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
*
*
* @name Phaser.GameObjects.Components.Tint#tintBottomRight
* @type {integer}
* @webglOnly
@ -288,7 +280,7 @@ var Tint = {
set: function (value)
{
this._tintBR = GetColor(value);
this._tintBR = GetColorFromValue(value);
this._isTinted = true;
}
@ -297,7 +289,7 @@ var Tint = {
/**
* The tint value being applied to the whole of the Game Object.
* This property is a setter-only. Use the properties `tintTopLeft` etc to read the current tint value.
*
*
* @name Phaser.GameObjects.Components.Tint#tint
* @type {integer}
* @webglOnly
@ -313,7 +305,7 @@ var Tint = {
/**
* Does this Game Object have a tint applied to it or not?
*
*
* @name Phaser.GameObjects.Components.Tint#isTinted
* @type {boolean}
* @webglOnly

View file

@ -6,8 +6,10 @@
var MATH_CONST = require('../../math/const');
var TransformMatrix = require('./TransformMatrix');
var TransformXY = require('../../math/TransformXY');
var WrapAngle = require('../../math/angle/Wrap');
var WrapAngleDegrees = require('../../math/angle/WrapDegrees');
var Vector2 = require('../../math/Vector2');
// global bitmask flag for GameObject.renderMask (used by Scale)
var _FLAG = 4; // 0100
@ -502,6 +504,56 @@ var Transform = {
return tempMatrix;
},
/**
* Takes the given `x` and `y` coordinates and converts them into local space for this
* Game Object, taking into account parent and local transforms, and the Display Origin.
*
* The returned Vector2 contains the translated point in its properties.
*
* A Camera needs to be provided in order to handle modified scroll factors. If no
* camera is specified, it will use the `main` camera from the Scene to which this
* Game Object belongs.
*
* @method Phaser.GameObjects.Components.Transform#getLocalPoint
* @since 3.50.0
*
* @param {number} x - The x position to translate.
* @param {number} y - The y position to translate.
* @param {Phaser.Math.Vector2} [point] - A Vector2, or point-like object, to store the results in.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera which is being tested against. If not given will use the Scene default camera.
*
* @return {Phaser.Math.Vector2} The translated point.
*/
getLocalPoint: function (x, y, point, camera)
{
if (!point) { point = new Vector2(); }
if (!camera) { camera = this.scene.sys.cameras.main; }
var csx = camera.scrollX;
var csy = camera.scrollY;
var px = x + (csx * this.scrollFactorX) - csx;
var py = y + (csy * this.scrollFactorY) - csy;
if (this.parentContainer)
{
this.getWorldTransformMatrix().applyInverse(px, py, point);
}
else
{
TransformXY(px, py, this.x, this.y, this.rotation, this.scaleX, this.scaleY, point);
}
// Normalize origin
if (this._originComponent)
{
point.x += this._displayOriginX;
point.y += this._displayOriginY;
}
return point;
},
/**
* Gets the sum total rotation of all of this Game Objects parent Containers.
*

View file

@ -930,6 +930,58 @@ var TransformMatrix = new Class({
return x * this.b + y * this.d + this.f;
},
/**
* Returns the X component of this matrix multiplied by the given values.
*
* This is the same as `x * a + y * c + e`, optionally passing via `Math.round`.
*
* @method Phaser.GameObjects.Components.TransformMatrix#getXRound
* @since 3.50.0
*
* @param {number} x - The x value.
* @param {number} y - The y value.
* @param {boolean} [round=false] - Math.round the resulting value?
*
* @return {number} The calculated x value.
*/
getXRound: function (x, y, round)
{
var v = this.getX(x, y);
if (round)
{
v = Math.round(v);
}
return v;
},
/**
* Returns the Y component of this matrix multiplied by the given values.
*
* This is the same as `x * b + y * d + f`, optionally passing via `Math.round`.
*
* @method Phaser.GameObjects.Components.TransformMatrix#getYRound
* @since 3.50.0
*
* @param {number} x - The x value.
* @param {number} y - The y value.
* @param {boolean} [round=false] - Math.round the resulting value?
*
* @return {number} The calculated y value.
*/
getYRound: function (x, y, round)
{
var v = this.getY(x, y);
if (round)
{
v = Math.round(v);
}
return v;
},
/**
* Returns a string that can be used in a CSS Transform call as a `matrix` property.
*

View file

@ -26,6 +26,10 @@ var Vector2 = require('../../math/Vector2');
*
* The position of the Game Object automatically becomes relative to the position of the Container.
*
* The origin of a Container is 0x0 (in local space) and that cannot be changed. The children you add to the
* Container should be positioned with this value in mind. I.e. you should treat 0x0 as being the center of
* the Container, and position children positively and negative around it as required.
*
* When the Container is rendered, all of its children are rendered as well, in the order in which they exist
* within the Container. Container children can be repositioned using methods such as `MoveUp`, `MoveDown` and `SendToBack`.
*
@ -198,14 +202,14 @@ var Container = new Class({
*
* When a camera scrolls it will change the location at which this Container is rendered on-screen.
* It does not change the Containers actual position values.
*
*
* For a Container, setting this value will only update the Container itself, not its children.
* If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method.
*
* A value of 1 means it will move exactly in sync with a camera.
* A value of 0 means it will not move at all, even if the camera moves.
* Other values control the degree to which the camera movement is mapped to this Container.
*
*
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
* calculating physics collisions. Bodies always collide based on their world position, but changing
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
@ -225,14 +229,14 @@ var Container = new Class({
*
* When a camera scrolls it will change the location at which this Container is rendered on-screen.
* It does not change the Containers actual position values.
*
*
* For a Container, setting this value will only update the Container itself, not its children.
* If you wish to change the scrollFactor of the children as well, use the `setScrollFactor` method.
*
* A value of 1 means it will move exactly in sync with a camera.
* A value of 0 means it will not move at all, even if the camera moves.
* Other values control the degree to which the camera movement is mapped to this Container.
*
*
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
* calculating physics collisions. Bodies always collide based on their world position, but changing
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
@ -384,10 +388,21 @@ var Container = new Class({
output.setTo(this.x, this.y, 0, 0);
if (this.parentContainer)
{
var parentMatrix = this.parentContainer.getBoundsTransformMatrix();
var transformedPosition = parentMatrix.transformPoint(this.x, this.y);
output.setTo(transformedPosition.x, transformedPosition.y, 0, 0);
}
if (this.list.length > 0)
{
var children = this.list;
var tempRect = new Rectangle();
var hasSetFirst = false;
output.setEmpty();
for (var i = 0; i < children.length; i++)
{
@ -397,7 +412,15 @@ var Container = new Class({
{
entry.getBounds(tempRect);
Union(tempRect, output, output);
if (!hasSetFirst)
{
output.setTo(tempRect.x, tempRect.y, tempRect.width, tempRect.height);
hasSetFirst = true;
}
else
{
Union(tempRect, output, output);
}
}
}
}
@ -468,7 +491,11 @@ var Container = new Class({
if (this.parentContainer)
{
return this.parentContainer.pointToContainer(source, output);
this.parentContainer.pointToContainer(source, output);
}
else
{
output = new Vector2(source.x, source.y);
}
var tempMatrix = this.tempTransformMatrix;
@ -485,7 +512,7 @@ var Container = new Class({
/**
* Returns the world transform matrix as used for Bounds checks.
*
*
* The returned matrix is temporal and shouldn't be stored.
*
* @method Phaser.GameObjects.Container#getBoundsTransformMatrix
@ -1135,7 +1162,7 @@ var Container = new Class({
* A value of 1 means it will move exactly in sync with a camera.
* A value of 0 means it will not move at all, even if the camera moves.
* Other values control the degree to which the camera movement is mapped to this Game Object.
*
*
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
* calculating physics collisions. Bodies always collide based on their world position, but changing
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset

View file

@ -30,7 +30,7 @@ var ContainerCanvasRenderer = function (renderer, container, interpolationPercen
}
var transformMatrix = container.localTransform;
if (parentMatrix)
{
transformMatrix.loadIdentity();
@ -56,6 +56,11 @@ var ContainerCanvasRenderer = function (renderer, container, interpolationPercen
var scrollFactorX = container.scrollFactorX;
var scrollFactorY = container.scrollFactorY;
if (container.mask)
{
container.mask.preRenderCanvas(renderer, null, camera);
}
for (var i = 0; i < children.length; i++)
{
var child = children[i];
@ -86,6 +91,11 @@ var ContainerCanvasRenderer = function (renderer, container, interpolationPercen
child.setAlpha(childAlpha);
child.setScrollFactor(childScrollFactorX, childScrollFactorY);
}
if (container.mask)
{
container.mask.postRenderCanvas(renderer);
}
};
module.exports = ContainerCanvasRenderer;

View file

@ -16,8 +16,8 @@ var GameObjectFactory = require('../GameObjectFactory');
* @method Phaser.GameObjects.GameObjectFactory#container
* @since 3.4.0
*
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {number} [x=0] - The horizontal position of this Game Object in the world.
* @param {number} [y=0] - The vertical position of this Game Object in the world.
* @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} [children] - An optional array of Game Objects to add to this Container.
*
* @return {Phaser.GameObjects.Container} The Game Object that was created.

View file

@ -16,51 +16,54 @@ var Vector4 = require('../../math/Vector4');
/**
* @classdesc
* 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.
*
*
* They also cannot be enabled for input. To do that, you have to use the `addListener` method to add native event
* listeners directly. The final limitation is to do with cameras. The DOM Container is sized to match the game canvas
* entirely and clipped accordingly. DOM Elements respect camera scrolling and scrollFactor settings, but if you
* change the size of the camera so it no longer matches the size of the canvas, they won't be clipped accordingly.
*
*
* Also, all DOM Elements are inserted into the same DOM Container, regardless of which Scene they are created in.
*
*
* Note that you should only have DOM Elements in a Scene with a _single_ Camera. If you require multiple cameras,
* use parallel scenes to achieve this.
*
* DOM Elements are a powerful way to align native HTML with your Phaser Game Objects. For example, you can insert
* a login form for a multiplayer game directly into your title screen. Or a text input box for a highscore table.
* Or a banner ad from a 3rd party service. Or perhaps you'd like to use them for high resolution text display and
@ -111,7 +114,7 @@ var DOMElement = new Class({
/**
* A reference to the parent DOM Container that the Game instance created when it started.
*
*
* @name Phaser.GameObjects.DOMElement#parent
* @type {Element}
* @since 3.17.0
@ -120,7 +123,7 @@ var DOMElement = new Class({
/**
* A reference to the HTML Cache.
*
*
* @name Phaser.GameObjects.DOMElement#cache
* @type {Phaser.Cache.BaseCache}
* @since 3.17.0
@ -130,7 +133,7 @@ var DOMElement = new Class({
/**
* The actual DOM Element that this Game Object is bound to. For example, if you've created a `<div>`
* then this property is a direct reference to that element within the dom.
*
*
* @name Phaser.GameObjects.DOMElement#node
* @type {Element}
* @since 3.17.0
@ -142,10 +145,10 @@ var DOMElement = new Class({
* updated when its rendered. If, for some reason, you don't want any of these changed other than the
* CSS transform, then set this flag to `true`. When `true` only the CSS Transform is applied and it's
* up to you to keep track of and set the other properties as required.
*
*
* This can be handy if, for example, you've a nested DOM Element and you don't want the opacity to be
* picked-up by any of its children.
*
*
* @name Phaser.GameObjects.DOMElement#transformOnly
* @type {boolean}
* @since 3.17.0
@ -154,9 +157,9 @@ var DOMElement = new Class({
/**
* The angle, in radians, by which to skew the DOM Element on the horizontal axis.
*
*
* https://developer.mozilla.org/en-US/docs/Web/CSS/transform
*
*
* @name Phaser.GameObjects.DOMElement#skewX
* @type {number}
* @since 3.17.0
@ -165,9 +168,9 @@ var DOMElement = new Class({
/**
* The angle, in radians, by which to skew the DOM Element on the vertical axis.
*
*
* https://developer.mozilla.org/en-US/docs/Web/CSS/transform
*
*
* @name Phaser.GameObjects.DOMElement#skewY
* @type {number}
* @since 3.17.0
@ -176,13 +179,13 @@ var DOMElement = new Class({
/**
* A Vector4 that contains the 3D rotation of this DOM Element around a fixed axis in 3D space.
*
*
* All values in the Vector4 are treated as degrees, unless the `rotate3dAngle` property is changed.
*
*
* For more details see the following MDN page:
*
*
* https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d
*
*
* @name Phaser.GameObjects.DOMElement#rotate3d
* @type {Phaser.Math.Vector4}
* @since 3.17.0
@ -192,9 +195,9 @@ var DOMElement = new Class({
/**
* The unit that represents the 3D rotation values. By default this is `deg` for degrees, but can
* be changed to any supported unit. See this page for further details:
*
*
* https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/rotate3d
*
*
* @name Phaser.GameObjects.DOMElement#rotate3dAngle
* @type {string}
* @since 3.17.0
@ -203,11 +206,11 @@ var DOMElement = new Class({
/**
* The native (un-scaled) width of this Game Object.
*
*
* For a DOM Element this property is read-only.
*
*
* The property `displayWidth` holds the computed bounds of this DOM Element, factoring in scaling.
*
*
* @name Phaser.GameObjects.DOMElement#width
* @type {number}
* @readonly
@ -217,11 +220,11 @@ var DOMElement = new Class({
/**
* The native (un-scaled) height of this Game Object.
*
*
* For a DOM Element this property is read-only.
*
*
* The property `displayHeight` holds the computed bounds of this DOM Element, factoring in scaling.
*
*
* @name Phaser.GameObjects.DOMElement#height
* @type {number}
* @readonly
@ -231,9 +234,9 @@ var DOMElement = new Class({
/**
* The computed display width of this Game Object, based on the `getBoundingClientRect` DOM call.
*
*
* The property `width` holds the un-scaled width of this DOM Element.
*
*
* @name Phaser.GameObjects.DOMElement#displayWidth
* @type {number}
* @readonly
@ -243,9 +246,9 @@ var DOMElement = new Class({
/**
* The computed display height of this Game Object, based on the `getBoundingClientRect` DOM call.
*
*
* The property `height` holds the un-scaled height of this DOM Element.
*
*
* @name Phaser.GameObjects.DOMElement#displayHeight
* @type {number}
* @readonly
@ -255,7 +258,7 @@ var DOMElement = new Class({
/**
* Internal native event handler.
*
*
* @name Phaser.GameObjects.DOMElement#handler
* @type {number}
* @private
@ -299,7 +302,7 @@ var DOMElement = new Class({
{
var node = this.node;
var style = node.style;
if (node)
{
style.display = (sys.settings.visible) ? 'block' : 'none';
@ -308,7 +311,7 @@ var DOMElement = new Class({
/**
* Sets the horizontal and vertical skew values of this DOM Element.
*
*
* For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
*
* @method Phaser.GameObjects.DOMElement#setSkew
@ -316,7 +319,7 @@ var DOMElement = new Class({
*
* @param {number} [x=0] - The angle, in radians, by which to skew the DOM Element on the horizontal axis.
* @param {number} [y=x] - The angle, in radians, by which to skew the DOM Element on the vertical axis.
*
*
* @return {this} This DOM Element instance.
*/
setSkew: function (x, y)
@ -335,16 +338,16 @@ var DOMElement = new Class({
* plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with
* z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined
* by the value of this property.
*
*
* For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective
*
*
* **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.**
*
* @method Phaser.GameObjects.DOMElement#setPerspective
* @since 3.17.0
*
* @param {number} value - The perspective value, in pixels, that determines the distance between the z plane and the user.
*
*
* @return {this} This DOM Element instance.
*/
setPerspective: function (value)
@ -359,11 +362,11 @@ var DOMElement = new Class({
* plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with
* z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined
* by the value of this property.
*
*
* For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective
*
*
* **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.**
*
*
* @name Phaser.GameObjects.DOMElement#perspective
* @type {number}
* @since 3.17.0
@ -385,14 +388,14 @@ var DOMElement = new Class({
/**
* Adds one or more native DOM event listeners onto the underlying Element of this Game Object.
* The event is then dispatched via this Game Objects standard event emitter.
*
*
* For example:
*
*
* ```javascript
* var div = this.add.dom(x, y, element);
*
*
* div.addListener('click');
*
*
* div.on('click', handler);
* ```
*
@ -400,7 +403,7 @@ var DOMElement = new Class({
* @since 3.17.0
*
* @param {string} events - The DOM event/s to listen for. You can specify multiple events by separating them with spaces.
*
*
* @return {this} This DOM Element instance.
*/
addListener: function (events)
@ -425,7 +428,7 @@ var DOMElement = new Class({
* @since 3.17.0
*
* @param {string} events - The DOM event/s to stop listening for. You can specify multiple events by separating them with spaces.
*
*
* @return {this} This DOM Element instance.
*/
removeListener: function (events)
@ -460,22 +463,22 @@ var DOMElement = new Class({
/**
* Creates a native DOM Element, adds it to the parent DOM Container and then binds it to this Game Object,
* so you can control it. The `tagName` should be a string and is passed to `document.createElement`:
*
*
* ```javascript
* this.add.dom().createElement('div');
* ```
*
*
* For more details on acceptable tag names see: https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
*
*
* You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText`
* value as well. Here is an example of a DOMString:
*
*
* ```javascript
* this.add.dom().createElement('div', 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser');
* ```
*
*
* And using a style object:
*
*
* ```javascript
* var style = {
* 'background-color': 'lime';
@ -483,10 +486,10 @@ var DOMElement = new Class({
* 'height': '100px';
* 'font': '48px Arial';
* };
*
*
* this.add.dom().createElement('div', style, 'Phaser');
* ```
*
*
* If this Game Object already has an Element, it is removed from the DOM entirely first.
* Any event listeners you may have previously created will need to be re-created after this call.
*
@ -496,7 +499,7 @@ var DOMElement = new Class({
* @param {string} tagName - A string that specifies the type of element to be created. The nodeName of the created element is initialized with the value of tagName. Don't use qualified names (like "html:a") with this method.
* @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from.
* @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element.
*
*
* @return {this} This DOM Element instance.
*/
createElement: function (tagName, style, innerText)
@ -507,34 +510,34 @@ var DOMElement = new Class({
/**
* Binds a new DOM Element to this Game Object. If this Game Object already has an Element it is removed from the DOM
* entirely first. Any event listeners you may have previously created will need to be re-created on the new element.
*
*
* The `element` argument you pass to this method can be either a string tagName:
*
*
* ```javascript
* <h1 id="heading">Phaser</h1>
*
* this.add.dom().setElement('heading');
* ```
*
*
* Or a reference to an Element instance:
*
*
* ```javascript
* <h1 id="heading">Phaser</h1>
*
* var h1 = document.getElementById('heading');
*
*
* this.add.dom().setElement(h1);
* ```
*
*
* You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText`
* value as well. Here is an example of a DOMString:
*
*
* ```javascript
* this.add.dom().setElement(h1, 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser');
* ```
*
*
* And using a style object:
*
*
* ```javascript
* var style = {
* 'background-color': 'lime';
@ -542,7 +545,7 @@ var DOMElement = new Class({
* 'height': '100px';
* 'font': '48px Arial';
* };
*
*
* this.add.dom().setElement(h1, style, 'Phaser');
* ```
*
@ -552,7 +555,7 @@ var DOMElement = new Class({
* @param {(string|Element)} element - If a string it is passed to `getElementById()`, or it should be a reference to an existing Element.
* @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from.
* @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element.
*
*
* @return {this} This DOM Element instance.
*/
setElement: function (element, style, innerText)
@ -626,38 +629,38 @@ var DOMElement = new Class({
* Takes a block of html from the HTML Cache, that has previously been preloaded into the game, and then
* creates a DOM Element from it. The loaded HTML is set as the `innerHTML` property of the created
* element.
*
*
* Assume the following html is stored in a file called `loginform.html`:
*
*
* ```html
* <input type="text" name="nameField" placeholder="Enter your name" style="font-size: 32px">
* <input type="button" name="playButton" value="Let's Play" style="font-size: 32px">
* ```
*
*
* Which is loaded into your game using the cache key 'login':
*
*
* ```javascript
* this.load.html('login', 'assets/loginform.html');
* ```
*
*
* You can create a DOM Element from it using the cache key:
*
*
* ```javascript
* this.add.dom().createFromCache('login');
* ```
*
*
* The optional `elementType` argument controls the container that is created, into which the loaded html is inserted.
* The default is a plain `div` object, but any valid tagName can be given.
*
*
* If this Game Object already has an Element, it is removed from the DOM entirely first.
* Any event listeners you may have previously created will need to be re-created after this call.
*
* @method Phaser.GameObjects.DOMElement#createFromCache
* @since 3.17.0
*
*
* @param {string} The key of the html cache entry to use for this DOM Element.
* @param {string} [tagName='div'] - The tag name of the element into which all of the loaded html will be inserted. Defaults to a plain div tag.
*
*
* @return {this} This DOM Element instance.
*/
createFromCache: function (key, tagName)
@ -675,32 +678,32 @@ var DOMElement = new Class({
/**
* Takes a string of html and then creates a DOM Element from it. The HTML is set as the `innerHTML`
* property of the created element.
*
*
* ```javascript
* let form = `
* <input type="text" name="nameField" placeholder="Enter your name" style="font-size: 32px">
* <input type="button" name="playButton" value="Let's Play" style="font-size: 32px">
* `;
* ```
*
*
* You can create a DOM Element from it using the string:
*
*
* ```javascript
* this.add.dom().createFromHTML(form);
* ```
*
*
* The optional `elementType` argument controls the type of container that is created, into which the html is inserted.
* The default is a plain `div` object, but any valid tagName can be given.
*
*
* If this Game Object already has an Element, it is removed from the DOM entirely first.
* Any event listeners you may have previously created will need to be re-created after this call.
*
* @method Phaser.GameObjects.DOMElement#createFromHTML
* @since 3.17.0
*
*
* @param {string} A string of html to be set as the `innerHTML` property of the created element.
* @param {string} [tagName='div'] - The tag name of the element into which all of the html will be inserted. Defaults to a plain div tag.
*
*
* @return {this} This DOM Element instance.
*/
createFromHTML: function (html, tagName)
@ -738,7 +741,7 @@ var DOMElement = new Class({
*
* @method Phaser.GameObjects.DOMElement#removeElement
* @since 3.17.0
*
*
* @return {this} This DOM Element instance.
*/
removeElement: function ()
@ -757,12 +760,12 @@ var DOMElement = new Class({
* Internal method that calls `getBoundingClientRect` on the `node` and then sets the bounds width
* and height into the `displayWidth` and `displayHeight` properties, and the `clientWidth` and `clientHeight`
* values into the `width` and `height` properties respectively.
*
*
* This is called automatically whenever a new element is created or set.
*
* @method Phaser.GameObjects.DOMElement#updateSize
* @since 3.17.0
*
*
* @return {this} This DOM Element instance.
*/
updateSize: function ()
@ -787,10 +790,10 @@ var DOMElement = new Class({
*
* @method Phaser.GameObjects.DOMElement#getChildByProperty
* @since 3.17.0
*
*
* @param {string} property - The property to search the children for.
* @param {string} value - The value the property must strictly equal.
*
*
* @return {?Element} The first matching child DOM Element, or `null` if not found.
*/
getChildByProperty: function (property, value)
@ -814,14 +817,14 @@ var DOMElement = new Class({
/**
* Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through
* them, looking for the first one that has a matching id. It then returns this child if found, or `null` if not.
*
*
* Be aware that class and id names are case-sensitive.
*
* @method Phaser.GameObjects.DOMElement#getChildByID
* @since 3.17.0
*
*
* @param {string} id - The id to search the children for.
*
*
* @return {?Element} The first matching child DOM Element, or `null` if not found.
*/
getChildByID: function (id)
@ -832,14 +835,14 @@ var DOMElement = new Class({
/**
* Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through
* them, looking for the first one that has a matching name. It then returns this child if found, or `null` if not.
*
*
* Be aware that class and id names are case-sensitive.
*
* @method Phaser.GameObjects.DOMElement#getChildByName
* @since 3.17.0
*
*
* @param {string} name - The name to search the children for.
*
*
* @return {?Element} The first matching child DOM Element, or `null` if not found.
*/
getChildByName: function (name)
@ -852,9 +855,9 @@ var DOMElement = new Class({
*
* @method Phaser.GameObjects.DOMElement#setClassName
* @since 3.17.0
*
*
* @param {string} className - A string representing the class or space-separated classes of the element.
*
*
* @return {this} This DOM Element instance.
*/
setClassName: function (className)
@ -871,14 +874,14 @@ var DOMElement = new Class({
/**
* Sets the `innerText` property of the DOM Element node and updates the internal sizes.
*
*
* Note that only certain types of Elements can have `innerText` set on them.
*
* @method Phaser.GameObjects.DOMElement#setText
* @since 3.17.0
*
*
* @param {string} text - A DOMString representing the rendered text content of the element.
*
*
* @return {this} This DOM Element instance.
*/
setText: function (text)
@ -898,9 +901,9 @@ var DOMElement = new Class({
*
* @method Phaser.GameObjects.DOMElement#setHTML
* @since 3.17.0
*
*
* @param {string} html - A DOMString of html to be set as the `innerHTML` property of the element.
*
*
* @return {this} This DOM Element instance.
*/
setHTML: function (html)
@ -935,7 +938,7 @@ var DOMElement = new Class({
/**
* Compares the renderMask with the renderFlags to see if this Game Object will render or not.
*
*
* DOMElements always return `true` as they need to still set values during the render pass, even if not visible.
*
* @method Phaser.GameObjects.DOMElement#willRender

View file

@ -502,7 +502,7 @@ var Graphics = new Class({
/**
* Fill the current path.
*
*
* This is an alias for `Graphics.fillPath` and does the same thing.
* It was added to match the CanvasRenderingContext 2D API.
*
@ -539,7 +539,7 @@ var Graphics = new Class({
/**
* Stroke the current path.
*
*
* This is an alias for `Graphics.strokePath` and does the same thing.
* It was added to match the CanvasRenderingContext 2D API.
*
@ -1034,7 +1034,7 @@ var Graphics = new Class({
* Stroke the shape represented by the given array of points.
*
* Pass `closeShape` to automatically close the shape by joining the last to the first point.
*
*
* Pass `closePath` to automatically close the path before it is stroked.
*
* @method Phaser.GameObjects.Graphics#strokePoints
@ -1081,7 +1081,7 @@ var Graphics = new Class({
* Fill the shape represented by the given array of points.
*
* Pass `closeShape` to automatically close the shape by joining the last to the first point.
*
*
* Pass `closePath` to automatically close the path before it is filled.
*
* @method Phaser.GameObjects.Graphics#fillPoints
@ -1218,7 +1218,7 @@ var Graphics = new Class({
* Draw an arc.
*
* This method can be used to create circles, or parts of circles.
*
*
* Make sure you call `beginPath` before starting the arc unless you wish for the arc to automatically
* close when filled or stroked.
*
@ -1336,10 +1336,10 @@ var Graphics = new Class({
/**
* Inserts a translation command into this Graphics objects command buffer.
*
*
* All objects drawn _after_ calling this method will be translated
* by the given amount.
*
*
* This does not change the position of the Graphics object itself,
* only of the objects drawn by it after calling this method.
*
@ -1363,10 +1363,10 @@ var Graphics = new Class({
/**
* Inserts a scale command into this Graphics objects command buffer.
*
*
* All objects drawn _after_ calling this method will be scaled
* by the given amount.
*
*
* This does not change the scale of the Graphics object itself,
* only of the objects drawn by it after calling this method.
*
@ -1390,10 +1390,10 @@ var Graphics = new Class({
/**
* Inserts a rotation command into this Graphics objects command buffer.
*
*
* All objects drawn _after_ calling this method will be rotated
* by the given amount.
*
*
* This does not change the rotation of the Graphics object itself,
* only of the objects drawn by it after calling this method.
*
@ -1448,6 +1448,10 @@ var Graphics = new Class({
* If `key` is a Canvas it will draw the texture to that canvas context. Note that it will NOT
* automatically upload it to the GPU in WebGL mode.
*
* Please understand that the texture is created via the Canvas API of the browser, therefore some
* Graphics features, such as `fillGradientStyle`, will not appear on the resulting texture,
* as they're unsupported by the Canvas API.
*
* @method Phaser.GameObjects.Graphics#generateTexture
* @since 3.0.0
*

View file

@ -104,7 +104,8 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca
var getTint = Utils.getTintAppendFloatAlphaAndSwap;
var currentTexture = renderer.blankTexture.glTexture;
// Set to a white texture, not a blank one, so Lights2D works too!
var currentTexture = renderer.tempTextures[0];
for (var cmdIndex = 0; cmdIndex < commands.length; cmdIndex++)
{
@ -132,7 +133,7 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca
case Commands.FILL_PATH:
for (pathIndex = 0; pathIndex < path.length; pathIndex++)
{
pipeline.setTexture2D(currentTexture);
pipeline.setTexture2D(currentTexture, src);
pipeline.batchFillPath(
path[pathIndex].points,
@ -145,7 +146,7 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca
case Commands.STROKE_PATH:
for (pathIndex = 0; pathIndex < path.length; pathIndex++)
{
pipeline.setTexture2D(currentTexture);
pipeline.setTexture2D(currentTexture, src);
pipeline.batchStrokePath(
path[pathIndex].points,
@ -254,7 +255,7 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca
break;
case Commands.FILL_RECT:
pipeline.setTexture2D(currentTexture);
pipeline.setTexture2D(currentTexture, src);
pipeline.batchFillRect(
commands[++cmdIndex],
commands[++cmdIndex],
@ -266,7 +267,7 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca
break;
case Commands.FILL_TRIANGLE:
pipeline.setTexture2D(currentTexture);
pipeline.setTexture2D(currentTexture, src);
pipeline.batchFillTriangle(
commands[++cmdIndex],
commands[++cmdIndex],
@ -280,7 +281,7 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca
break;
case Commands.STROKE_TRIANGLE:
pipeline.setTexture2D(currentTexture);
pipeline.setTexture2D(currentTexture, src);
pipeline.batchStrokeTriangle(
commands[++cmdIndex],
commands[++cmdIndex],
@ -340,7 +341,7 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca
var mode = commands[++cmdIndex];
pipeline.currentFrame = frame;
pipeline.setTexture2D(frame.glTexture, 0);
pipeline.setTexture2D(frame.glTexture, src);
pipeline.tintEffect = mode;
currentTexture = frame.glTexture;
@ -350,7 +351,7 @@ var GraphicsWebGLRenderer = function (renderer, src, interpolationPercentage, ca
case Commands.CLEAR_TEXTURE:
pipeline.currentFrame = renderer.blankTexture;
pipeline.tintEffect = 2;
currentTexture = renderer.blankTexture.glTexture;
currentTexture = renderer.tempTextures[0];
break;
}
}

View file

@ -91,7 +91,7 @@ var Group = new Class({
* @type {Phaser.Structs.Set.<Phaser.GameObjects.GameObject>}
* @since 3.0.0
*/
this.children = new Set(children);
this.children = new Set();
/**
* A flag identifying this object as a group.
@ -136,8 +136,7 @@ var Group = new Class({
this.name = GetFastValue(config, 'name', '');
/**
* Whether this group runs its {@link Phaser.GameObjects.Group#preUpdate} method
* (which may update any members).
* Whether this group runs its {@link Phaser.GameObjects.Group#preUpdate} method (which may update any members).
*
* @name Phaser.GameObjects.Group#active
* @type {boolean}
@ -236,6 +235,11 @@ var Group = new Class({
*/
this.internalRemoveCallback = GetFastValue(config, 'internalRemoveCallback', null);
if (children)
{
this.addMultiple(children);
}
if (config)
{
this.createMultiple(config);
@ -1103,6 +1107,42 @@ var Group = new Class({
return (capacity - used);
},
/**
* Sets the `active` property of this Group.
* When active, this Group runs its `preUpdate` method.
*
* @method Phaser.GameObjects.Group#setActive
* @since 3.24.0
*
* @param {boolean} value - True if this Group should be set as active, false if not.
*
* @return {this} This Group object.
*/
setActive: function (value)
{
this.active = value;
return this;
},
/**
* Sets the `name` property of this Group.
* The `name` property is not populated by Phaser and is presented for your own use.
*
* @method Phaser.GameObjects.Group#setName
* @since 3.24.0
*
* @param {string} value - The name to be given to this Group.
*
* @return {this} This Group object.
*/
setName: function (value)
{
this.name = value;
return this;
},
/**
* Sets the property as defined in `key` of each group member to the given value.
*
@ -1260,7 +1300,7 @@ var Group = new Class({
/**
* Iterate through the group members changing the position of each element to be that of the element that came before
* it in the array (or after it if direction = 1)
*
*
* The first group member position is set to x/y.
*
* @method Phaser.GameObjects.Group#shiftPosition

View file

@ -42,7 +42,7 @@ var ImageRender = require('./ImageRender');
* @param {Phaser.Scene} scene - The Scene to which this Game Object belongs. A Game Object can only belong to one Scene at a time.
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|integer)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*/
var Image = new Class({

View file

@ -17,7 +17,7 @@ var GameObjectFactory = require('../GameObjectFactory');
*
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|integer)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*
* @return {Phaser.GameObjects.Image} The Game Object that was created.

View file

@ -13,7 +13,7 @@ var Utils = require('../../renderer/webgl/Utils');
*
* These are typically created by a {@link Phaser.GameObjects.LightsManager}, available from within a scene via `this.lights`.
*
* Any Game Objects using the Light2D pipeline will then be affected by these Lights.
* Any Game Objects using the Light2D pipeline will then be affected by these Lights as long as they have a normal map.
*
* They can also simply be used to represent a point light for your own purposes.
*
@ -39,83 +39,101 @@ var Light = new Class({
/**
* The horizontal position of the light.
*
* @name Phaser.GameObjects.Light#x
* @name Phaser.GameObjects.Light#_x
* @type {number}
* @private
* @since 3.0.0
*/
this.x = x;
this._x = x;
/**
* The vertical position of the light.
*
* @name Phaser.GameObjects.Light#y
* @name Phaser.GameObjects.Light#_y
* @type {number}
* @private
* @since 3.0.0
*/
this.y = y;
this._y = y;
/**
* The radius of the light.
*
* @name Phaser.GameObjects.Light#radius
* @name Phaser.GameObjects.Light#_radius
* @type {number}
* @private
* @since 3.0.0
*/
this.radius = radius;
this._radius = radius;
/**
* The red color of the light. A value between 0 and 1.
*
* @name Phaser.GameObjects.Light#r
* @name Phaser.GameObjects.Light#_r
* @type {number}
* @private
* @since 3.0.0
*/
this.r = r;
this._r = r;
/**
* The green color of the light. A value between 0 and 1.
*
* @name Phaser.GameObjects.Light#g
* @name Phaser.GameObjects.Light#_g
* @type {number}
* @private
* @since 3.0.0
*/
this.g = g;
this._g = g;
/**
* The blue color of the light. A value between 0 and 1.
*
* @name Phaser.GameObjects.Light#b
* @name Phaser.GameObjects.Light#_b
* @type {number}
* @private
* @since 3.0.0
*/
this.b = b;
this._b = b;
/**
* The intensity of the light.
*
* @name Phaser.GameObjects.Light#intensity
* @name Phaser.GameObjects.Light#_intensity
* @type {number}
* @private
* @since 3.0.0
*/
this.intensity = intensity;
this._intensity = intensity;
/**
* The horizontal scroll factor of the light.
*
* @name Phaser.GameObjects.Light#scrollFactorX
* @name Phaser.GameObjects.Light#_scrollFactorX
* @type {number}
* @private
* @since 3.0.0
*/
this.scrollFactorX = 1.0;
this._scrollFactorX = 1;
/**
* The vertical scroll factor of the light.
*
* @name Phaser.GameObjects.Light#scrollFactorY
* @name Phaser.GameObjects.Light#_scrollFactorY
* @type {number}
* @private
* @since 3.0.0
*/
this.scrollFactorY = 1.0;
this._scrollFactorY = 1;
/**
* The dirty state of the light. A dirty light will reset all of its shader attributes.
*
* @name Phaser.GameObjects.Light#dirty
* @type {boolean}
* @since 3.50.0
*/
this.dirty = true;
},
/**
@ -139,19 +157,21 @@ var Light = new Class({
*/
set: function (x, y, radius, r, g, b, intensity)
{
this.x = x;
this.y = y;
this._x = x;
this._y = y;
this.radius = radius;
this._radius = radius;
this.r = r;
this.g = g;
this.b = b;
this._r = r;
this._g = g;
this._b = b;
this.intensity = intensity;
this._intensity = intensity;
this.scrollFactorX = 1;
this.scrollFactorY = 1;
this._scrollFactorX = 1;
this._scrollFactorY = 1;
this.dirty = true;
return this;
},
@ -162,8 +182,8 @@ var Light = new Class({
* @method Phaser.GameObjects.Light#setScrollFactor
* @since 3.0.0
*
* @param {number} x - The horizontal scroll factor of the light.
* @param {number} y - The vertical scroll factor of the light.
* @param {number} [x=1] - The horizontal scroll factor of the light.
* @param {number} [y=x] - The vertical scroll factor of the light.
*
* @return {this} This Light object.
*/
@ -172,8 +192,10 @@ var Light = new Class({
if (x === undefined) { x = 1; }
if (y === undefined) { y = x; }
this.scrollFactorX = x;
this.scrollFactorY = y;
this._scrollFactorX = x;
this._scrollFactorY = y;
this.dirty = true;
return this;
},
@ -192,9 +214,11 @@ var Light = new Class({
{
var color = Utils.getFloatsFromUintRGB(rgb);
this.r = color[0];
this.g = color[1];
this.b = color[2];
this._r = color[0];
this._g = color[1];
this._b = color[2];
this.dirty = true;
return this;
},
@ -211,7 +235,9 @@ var Light = new Class({
*/
setIntensity: function (intensity)
{
this.intensity = intensity;
this._intensity = intensity;
this.dirty = true;
return this;
},
@ -229,8 +255,10 @@ var Light = new Class({
*/
setPosition: function (x, y)
{
this.x = x;
this.y = y;
this._x = x;
this._y = y;
this.dirty = true;
return this;
},
@ -247,9 +275,209 @@ var Light = new Class({
*/
setRadius: function (radius)
{
this.radius = radius;
this._radius = radius;
this.dirty = true;
return this;
},
/**
* The horizontal position of the light.
*
* @name Phaser.GameObjects.Light#x
* @type {number}
* @since 3.0.0
*/
x: {
get: function ()
{
return this._x;
},
set: function (value)
{
this._x = value;
this.dirty = true;
}
},
/**
* The vertical position of the light.
*
* @name Phaser.GameObjects.Light#y
* @type {number}
* @since 3.0.0
*/
y: {
get: function ()
{
return this._y;
},
set: function (value)
{
this._y = value;
this.dirty = true;
}
},
/**
* The radius of the light.
*
* @name Phaser.GameObjects.Light#radius
* @type {number}
* @since 3.0.0
*/
radius: {
get: function ()
{
return this._radius;
},
set: function (value)
{
this._radius = value;
this.dirty = true;
}
},
/**
* The red color of the light. A value between 0 and 1.
*
* @name Phaser.GameObjects.Light#r
* @type {number}
* @since 3.0.0
*/
r: {
get: function ()
{
return this._r;
},
set: function (value)
{
this._r = value;
this.dirty = true;
}
},
/**
* The green color of the light. A value between 0 and 1.
*
* @name Phaser.GameObjects.Light#g
* @type {number}
* @since 3.0.0
*/
g: {
get: function ()
{
return this._g;
},
set: function (value)
{
this._g = value;
this.dirty = true;
}
},
/**
* The blue color of the light. A value between 0 and 1.
*
* @name Phaser.GameObjects.Light#b
* @type {number}
* @since 3.0.0
*/
b: {
get: function ()
{
return this._b;
},
set: function (value)
{
this._b = value;
this.dirty = true;
}
},
/**
* The intensity of the light.
*
* @name Phaser.GameObjects.Light#intensity
* @type {number}
* @since 3.0.0
*/
intensity: {
get: function ()
{
return this._intensity;
},
set: function (value)
{
this._intensity = value;
this.dirty = true;
}
},
/**
* The horizontal scroll factor of the light.
*
* @name Phaser.GameObjects.Light#scrollFactorX
* @type {number}
* @since 3.0.0
*/
scrollFactorX: {
get: function ()
{
return this._scrollFactorX;
},
set: function (value)
{
this._scrollFactorX = value;
this.dirty = true;
}
},
/**
* The vertical scroll factor of the light.
*
* @name Phaser.GameObjects.Light#scrollFactorY
* @type {number}
* @since 3.0.0
*/
scrollFactorY: {
get: function ()
{
return this._scrollFactorY;
},
set: function (value)
{
this._scrollFactorY = value;
this.dirty = true;
}
}
});

View file

@ -153,13 +153,13 @@ var LightsManager = new Class({
var cameraRadius = (camera.width + camera.height) / 2.0;
var point = { x: 0, y: 0 };
var cameraMatrix = camera.matrix;
var viewportHeight = this.systems.game.config.height;
var viewportHeight = this.systems.game.renderer.height;
culledLights.length = 0;
for (var index = 0; index < length && culledLights.length < this.maxLights; index++)
for (var i = 0; i < length && culledLights.length < this.maxLights; i++)
{
var light = lights[index];
var light = lights[i];
cameraMatrix.transformPoint(light.x, light.y, point);
@ -170,7 +170,7 @@ var LightsManager = new Class({
if (distance < light.radius + cameraRadius)
{
culledLights.push(lights[index]);
culledLights.push(lights[i]);
}
}
@ -197,9 +197,9 @@ var LightsManager = new Class({
var lights = this.lights;
var length = lights.length;
for (var index = 0; index < length; ++index)
for (var i = 0; i < length; i++)
{
callback(lights[index]);
callback(lights[i]);
}
return this;
@ -268,21 +268,25 @@ var LightsManager = new Class({
*/
addLight: function (x, y, radius, rgb, intensity)
{
if (x === undefined) { x = 0; }
if (y === undefined) { y = 0; }
if (radius === undefined) { radius = 100; }
if (rgb === undefined) { rgb = 0xffffff; }
if (intensity === undefined) { intensity = 1; }
var color = null;
var light = null;
x = (x === undefined) ? 0.0 : x;
y = (y === undefined) ? 0.0 : y;
rgb = (rgb === undefined) ? 0xffffff : rgb;
radius = (radius === undefined) ? 100.0 : radius;
intensity = (intensity === undefined) ? 1.0 : intensity;
color = Utils.getFloatsFromUintRGB(rgb);
light = null;
if (this.lightPool.length > 0)
var pool = this.lightPool;
if (pool.length > 0)
{
light = this.lightPool.pop();
light = pool.pop();
light.set(x, y, radius, color[0], color[1], color[2], intensity);
}
else
@ -350,6 +354,8 @@ var LightsManager = new Class({
destroy: function ()
{
this.shutdown();
this.lightPool.length = 0;
}
});

View file

@ -38,7 +38,7 @@ var NOOP = require('../../utils/NOOP');
* @param {number[]} uv - An array containing the uv data for this Mesh.
* @param {number[]} colors - An array containing the color data for this Mesh.
* @param {number[]} alphas - An array containing the alpha data for this Mesh.
* @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|integer)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*/
var Mesh = new Class({
@ -137,7 +137,7 @@ var Mesh = new Class({
/**
* Fill or additive mode used when blending the color values?
*
*
* @name Phaser.GameObjects.Mesh#tintFill
* @type {boolean}
* @default false
@ -154,7 +154,7 @@ var Mesh = new Class({
/**
* This method is left intentionally empty and does not do anything.
* It is retained to allow a Mesh or Quad to be added to a Container.
*
*
* @method Phaser.GameObjects.Mesh#setAlpha
* @since 3.17.0
*/

View file

@ -22,7 +22,7 @@ var GameObjectFactory = require('../GameObjectFactory');
* @param {number[]} uv - An array containing the uv data for this Mesh.
* @param {number[]} colors - An array containing the color data for this Mesh.
* @param {number[]} alphas - An array containing the alpha data for this Mesh.
* @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|integer)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*
* @return {Phaser.GameObjects.Mesh} The Game Object that was created.

View file

@ -56,9 +56,6 @@ var MeshWebGLRenderer = function (renderer, src, interpolationPercentage, camera
camMatrix.multiply(spriteMatrix, calcMatrix);
}
var frame = src.frame;
var texture = frame.glTexture;
var vertices = src.vertices;
var uvs = src.uv;
var colors = src.colors;
@ -72,7 +69,7 @@ var MeshWebGLRenderer = function (renderer, src, interpolationPercentage, camera
pipeline.flush();
}
pipeline.setTexture2D(texture, 0);
var textureUnit = pipeline.setGameObject(src);
var vertexViewF32 = pipeline.vertexViewF32;
var vertexViewU32 = pipeline.vertexViewU32;
@ -100,6 +97,7 @@ var MeshWebGLRenderer = function (renderer, src, interpolationPercentage, camera
vertexViewF32[++vertexOffset] = ty;
vertexViewF32[++vertexOffset] = uvs[i + 0];
vertexViewF32[++vertexOffset] = uvs[i + 1];
vertexViewF32[++vertexOffset] = textureUnit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = Utils.getTintAppendFloatAlpha(colors[colorIndex], camera.alpha * alphas[colorIndex]);

View file

@ -15,7 +15,7 @@ var ParticleEmitterManager = require('./ParticleEmitterManager');
* @method Phaser.GameObjects.GameObjectFactory#particles
* @since 3.0.0
*
* @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|integer|object)} [frame] - An optional frame from the Texture this Game Object is rendering with.
* @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig|Phaser.Types.GameObjects.Particles.ParticleEmitterConfig[]} [emitters] - Configuration settings for one or more emitters to create.
*

View file

@ -46,7 +46,7 @@ var ParticleManagerWebGLRenderer = function (renderer, emitterManager, interpola
var texture = emitterManager.defaultFrame.glTexture;
var getTint = Utils.getTintAppendFloatAlphaAndSwap;
pipeline.setTexture2D(texture, 0);
var textureUnit = pipeline.setGameObject(emitterManager, emitterManager.defaultFrame);
for (var e = 0; e < emittersLength; e++)
{
@ -74,15 +74,16 @@ var ParticleManagerWebGLRenderer = function (renderer, emitterManager, interpola
if (renderer.setBlendMode(emitter.blendMode))
{
// Rebind the texture if we've flushed
pipeline.setTexture2D(texture, 0);
// pipeline.setTexture2D(texture, 0);
}
if (emitter.mask)
{
emitter.mask.preRenderWebGL(renderer, emitter, camera);
pipeline.setTexture2D(texture, 0);
// pipeline.setTexture2D(texture, 0);
}
var tintEffect = 0;
for (var i = 0; i < particleCount; i++)
@ -112,13 +113,13 @@ var ParticleManagerWebGLRenderer = function (renderer, emitterManager, interpola
var tx0 = calcMatrix.getX(x, y);
var ty0 = calcMatrix.getY(x, y);
var tx1 = calcMatrix.getX(x, yh);
var ty1 = calcMatrix.getY(x, yh);
var tx2 = calcMatrix.getX(xw, yh);
var ty2 = calcMatrix.getY(xw, yh);
var tx3 = calcMatrix.getX(xw, y);
var ty3 = calcMatrix.getY(xw, y);
@ -126,26 +127,27 @@ var ParticleManagerWebGLRenderer = function (renderer, emitterManager, interpola
{
tx0 = Math.round(tx0);
ty0 = Math.round(ty0);
tx1 = Math.round(tx1);
ty1 = Math.round(ty1);
tx2 = Math.round(tx2);
ty2 = Math.round(ty2);
tx3 = Math.round(tx3);
ty3 = Math.round(ty3);
}
var tint = getTint(particle.tint, alpha);
pipeline.batchQuad(tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, tintEffect, texture, 0);
pipeline.batchQuad(tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, tintEffect, texture, textureUnit);
}
if (emitter.mask)
{
emitter.mask.postRenderWebGL(renderer, camera);
pipeline.setTexture2D(texture, 0);
// pipeline.setTexture2D(texture, 0);
}
}
};

View file

@ -26,14 +26,14 @@ var Sprite = require('../sprite/Sprite');
* @memberof Phaser.GameObjects
* @constructor
* @since 3.0.0
*
*
* @extends Phaser.GameObjects.Components.PathFollower
*
* @param {Phaser.Scene} scene - The Scene to which this PathFollower belongs.
* @param {Phaser.Curves.Path} path - The Path this PathFollower is following. It can only follow one Path at a time.
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|integer)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*/
var PathFollower = new Class({

View file

@ -18,7 +18,7 @@ var PathFollower = require('./PathFollower');
* @param {Phaser.Curves.Path} path - The Path this PathFollower is connected to.
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|integer)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*
* @return {Phaser.GameObjects.PathFollower} The Game Object that was created.

View file

@ -27,7 +27,7 @@ var Mesh = require('../mesh/Mesh');
* @param {Phaser.Scene} scene - The Scene to which this Quad belongs.
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|integer)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*/
var Quad = new Class({

View file

@ -18,9 +18,9 @@ var GameObjectFactory = require('../GameObjectFactory');
*
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} texture - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|integer)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*
*
* @return {Phaser.GameObjects.Quad} The Game Object that was created.
*/
if (typeof WEBGL_RENDERER)
@ -32,9 +32,9 @@ if (typeof WEBGL_RENDERER)
}
// When registering a factory function 'this' refers to the GameObjectFactory context.
//
//
// There are several properties available to use:
//
//
// this.scene - a reference to the Scene that owns the GameObjectFactory
// this.displayList - a reference to the Display List the Scene owns
// this.updateList - a reference to the Update List the Scene owns

View file

@ -12,6 +12,8 @@ var Components = require('../components');
var CONST = require('../../const');
var Frame = require('../../textures/Frame');
var GameObject = require('../GameObject');
var NOOP = require('../../utils/NOOP');
var ProjectOrtho = require('../../renderer/webgl/mvp/ProjectOrtho');
var Render = require('./RenderTextureRender');
var Utils = require('../../renderer/webgl/Utils');
var UUID = require('../../utils/string/UUID');
@ -19,11 +21,11 @@ var UUID = require('../../utils/string/UUID');
/**
* @classdesc
* A Render Texture.
*
*
* A Render Texture is a special texture that allows any number of Game Objects to be drawn to it. You can take many complex objects and
* draw them all to this one texture, which can they be used as the texture for other Game Object's. It's a way to generate dynamic
* textures at run-time that are WebGL friendly and don't invoke expensive GPU uploads.
*
*
* Note that under WebGL a FrameBuffer, which is what the Render Texture uses internally, cannot be anti-aliased. This means
* that when drawing objects such as Shapes to a Render Texture they will appear to be drawn with no aliasing, however this
* is a technical limitation of WebGL. To get around it, create your shape as a texture in an art package, then draw that
@ -199,16 +201,16 @@ var RenderTexture = new Class({
{
this.canvas = CanvasPool.create2D(this, width, height);
// Create a new Texture for this Text object
// Create a new Texture for this RenderTexture object
this.texture = scene.sys.textures.addCanvas(UUID(), this.canvas);
// Get the frame
this.frame = this.texture.get();
}
else
{
this.texture = scene.sys.textures.get(key);
// Get the frame
this.frame = this.texture.get(frame);
@ -274,7 +276,11 @@ var RenderTexture = new Class({
var renderer = this.renderer;
if (renderer.type === CONST.WEBGL)
if (!renderer)
{
this.drawGameObject = NOOP;
}
else if (renderer.type === CONST.WEBGL)
{
var gl = renderer.gl;
@ -303,13 +309,13 @@ var RenderTexture = new Class({
/**
* Sets the size of this Game Object.
*
*
* @method Phaser.GameObjects.RenderTexture#setSize
* @since 3.0.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
*
* @return {this} This Game Object instance.
*/
setSize: function (width, height)
@ -319,7 +325,7 @@ var RenderTexture = new Class({
/**
* Resizes the Render Texture to the new dimensions given.
*
*
* If Render Texture was created from specific frame, only the size of the frame will be changed. The size of the source
* texture will not change.
*
@ -342,41 +348,47 @@ var RenderTexture = new Class({
{
if (height === undefined) { height = width; }
var frame = this.frame;
var renderer = this.renderer;
if (width !== this.width || height !== this.height)
{
if (this.frame.name === '__BASE')
if (frame.name === '__BASE')
{
// Resize the texture
this.canvas.width = width;
this.canvas.height = height;
this.texture.width = width;
this.texture.height = height;
if (this.gl)
{
var gl = this.gl;
this.renderer.deleteTexture(this.frame.source.glTexture);
this.renderer.deleteFramebuffer(this.framebuffer);
renderer.deleteTexture(frame.source.glTexture);
renderer.deleteFramebuffer(this.framebuffer);
var glTexture = this.renderer.createTexture2D(0, gl.NEAREST, gl.NEAREST, gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE, gl.RGBA, null, width, height, false);
var glTexture = renderer.createTexture2D(0, gl.NEAREST, gl.NEAREST, gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE, gl.RGBA, null, width, height, false);
this.framebuffer = this.renderer.createFramebuffer(width, height, glTexture, false);
this.framebuffer = renderer.createFramebuffer(width, height, glTexture, false);
this.frame.source.isRenderTexture = true;
frame.source.isRenderTexture = true;
frame.source.glTexture = glTexture;
frame.glTexture = glTexture;
this.frame.glTexture = glTexture;
this.glTexture = glTexture;
}
this.frame.source.width = width;
this.frame.source.height = height;
frame.source.width = width;
frame.source.height = height;
this.camera.setSize(width, height);
this.frame.setSize(width, height);
frame.setSize(width, height);
this.width = width;
this.height = height;
@ -388,17 +400,17 @@ var RenderTexture = new Class({
var baseFrame = this.texture.getSourceImage();
if (this.frame.cutX + width > baseFrame.width)
if (frame.cutX + width > baseFrame.width)
{
width = baseFrame.width - this.frame.cutX;
width = baseFrame.width - frame.cutX;
}
if (this.frame.cutY + height > baseFrame.height)
if (frame.cutY + height > baseFrame.height)
{
height = baseFrame.height - this.frame.cutY;
height = baseFrame.height - frame.cutY;
}
this.frame.setSize(width, height, this.frame.cutX, this.frame.cutY);
frame.setSize(width, height, frame.cutX, frame.cutY);
}
this.updateDisplayOrigin();
@ -450,24 +462,24 @@ var RenderTexture = new Class({
/**
* Stores a copy of this Render Texture in the Texture Manager using the given key.
*
*
* After doing this, any texture based Game Object, such as a Sprite, can use the contents of this
* Render Texture by using the texture key:
*
*
* ```javascript
* var rt = this.add.renderTexture(0, 0, 128, 128);
*
*
* // Draw something to the Render Texture
*
*
* rt.saveTexture('doodle');
*
*
* this.add.image(400, 300, 'doodle');
* ```
*
*
* Updating the contents of this Render Texture will automatically update _any_ Game Object
* that is using it as a texture. Calling `saveTexture` again will not save another copy
* of the same texture, it will just rename the key of the existing copy.
*
*
* By default it will create a single base texture. You can add frames to the texture
* by using the `Texture.add` method. After doing this, you can then allow Game Objects
* to use a specific frame from a Render Texture.
@ -482,7 +494,7 @@ var RenderTexture = new Class({
saveTexture: function (key)
{
this.textureManager.renameTexture(this.texture.key, key);
this._saved = true;
return this.texture;
@ -517,23 +529,27 @@ var RenderTexture = new Class({
var gl = this.gl;
var frame = this.frame;
var camera = this.camera;
var renderer = this.renderer;
this.camera.preRender(1, 1);
camera.preRender(1, 1);
if (gl)
{
var cx = this.camera._cx;
var cy = this.camera._cy;
var cw = this.camera._cw;
var ch = this.camera._ch;
var cx = camera._cx;
var cy = camera._cy;
var cw = camera._cw;
var ch = camera._ch;
this.renderer.setFramebuffer(this.framebuffer, false);
renderer.resetTextures(true);
this.renderer.pushScissor(cx, cy, cw, ch, ch);
renderer.setFramebuffer(this.framebuffer, false);
renderer.pushScissor(cx, cy, cw, ch, ch);
var pipeline = this.pipeline;
pipeline.projOrtho(0, this.texture.width, 0, this.texture.height, -1000.0, 1000.0);
ProjectOrtho(pipeline, 0, this.texture.width, 0, this.texture.height, -1000.0, 1000.0);
pipeline.drawFillRect(
x, y, width, height,
@ -541,20 +557,22 @@ var RenderTexture = new Class({
alpha
);
this.renderer.setFramebuffer(null, false);
pipeline.flush();
this.renderer.popScissor();
renderer.setFramebuffer(null, false);
pipeline.projOrtho(0, pipeline.width, pipeline.height, 0, -1000.0, 1000.0);
renderer.popScissor();
ProjectOrtho(pipeline, 0, pipeline.width, pipeline.height, 0, -1000.0, 1000.0);
}
else
{
this.renderer.setContext(this.context);
renderer.setContext(this.context);
this.context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')';
this.context.fillRect(x + frame.cutX, y + frame.cutY, width, height);
this.renderer.setContext();
renderer.setContext();
}
this.dirty = true;
@ -581,7 +599,7 @@ var RenderTexture = new Class({
var renderer = this.renderer;
renderer.setFramebuffer(this.framebuffer, true);
if (this.frame.cutWidth !== this.canvas.width || this.frame.cutHeight !== this.canvas.height)
{
gl.scissor(this.frame.cutX, this.frame.cutY, this.frame.cutWidth, this.frame.cutHeight);
@ -611,9 +629,9 @@ var RenderTexture = new Class({
/**
* Draws the given object, or an array of objects, to this Render Texture using a blend mode of ERASE.
* This has the effect of erasing any filled pixels in the objects from this Render Texture.
*
*
* It can 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.
@ -622,24 +640,24 @@ var RenderTexture = new Class({
* * Another Render Texture.
* * A Texture Frame instance.
* * A string. This is used to look-up a texture from the Texture Manager.
*
*
* Note: You cannot erase a Render Texture from itself.
*
*
* If passing in a Group or Container it will only draw children that return `true`
* when their `willRender()` method is called. I.e. a Container with 10 children,
* 5 of which have `visible=false` will only draw the 5 visible ones.
*
*
* If passing in an array of Game Objects it will draw them all, regardless if
* they pass a `willRender` check or not.
*
*
* You can pass in a string in which case it will look for a texture in the Texture
* Manager matching that string, and draw the base frame.
*
*
* You can pass in the `x` and `y` coordinates to draw the objects at. The use of
* the coordinates differ based on what objects are being drawn. If the object is
* a Group, Container or Display List, the coordinates are _added_ to the positions
* of the children. For all other types of object, the coordinates are exact.
*
*
* Calling this method causes the WebGL batch to flush, so it can write the texture
* data to the framebuffer being used internally. The batch is flushed at the end,
* after the entries have been iterated. So if you've a bunch of objects to draw,
@ -674,9 +692,9 @@ var RenderTexture = new Class({
/**
* Draws the given object, or an array of objects, to this Render Texture.
*
*
* It can accept any of the following:
*
*
* * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
* * Dynamic and Static Tilemap Layers.
* * A Group. The contents of which will be iterated and drawn in turn.
@ -685,28 +703,28 @@ var RenderTexture = new Class({
* * Another Render Texture.
* * A Texture Frame instance.
* * A string. This is used to look-up a texture from the Texture Manager.
*
*
* Note: You cannot draw a Render Texture to itself.
*
*
* If passing in a Group or Container it will only draw children that return `true`
* when their `willRender()` method is called. I.e. a Container with 10 children,
* 5 of which have `visible=false` will only draw the 5 visible ones.
*
*
* If passing in an array of Game Objects it will draw them all, regardless if
* they pass a `willRender` check or not.
*
*
* You can pass in a string in which case it will look for a texture in the Texture
* Manager matching that string, and draw the base frame. If you need to specify
* exactly which frame to draw then use the method `drawFrame` instead.
*
*
* You can pass in the `x` and `y` coordinates to draw the objects at. The use of
* the coordinates differ based on what objects are being drawn. If the object is
* a Group, Container or Display List, the coordinates are _added_ to the positions
* of the children. For all other types of object, the coordinates are exact.
*
*
* The `alpha` and `tint` values are only used by Texture Frames.
* Game Objects use their own alpha and tint values when being drawn.
*
*
* Calling this method causes the WebGL batch to flush, so it can write the texture
* data to the framebuffer being used internally. The batch is flushed at the end,
* after the entries have been iterated. So if you've a bunch of objects to draw,
@ -743,41 +761,44 @@ var RenderTexture = new Class({
}
var gl = this.gl;
var camera = this.camera;
var renderer = this.renderer;
this.camera.preRender(1, 1);
camera.preRender(1, 1);
if (gl)
{
var cx = this.camera._cx;
var cy = this.camera._cy;
var cw = this.camera._cw;
var ch = this.camera._ch;
var cx = camera._cx;
var cy = camera._cy;
var cw = camera._cw;
var ch = camera._ch;
this.renderer.setFramebuffer(this.framebuffer, false);
renderer.resetTextures(true);
this.renderer.pushScissor(cx, cy, cw, ch, ch);
renderer.setFramebuffer(this.framebuffer, false);
renderer.pushScissor(cx, cy, cw, ch, ch);
var pipeline = this.pipeline;
pipeline.projOrtho(0, this.texture.width, 0, this.texture.height, -1000.0, 1000.0);
ProjectOrtho(pipeline, 0, this.texture.width, 0, this.texture.height, -1000.0, 1000.0);
this.batchList(entries, x, y, alpha, tint);
pipeline.flush();
// Causes a flush + popScissor
renderer.setFramebuffer(null, true);
this.renderer.setFramebuffer(null, false);
renderer.resetTextures(true);
this.renderer.popScissor();
pipeline.projOrtho(0, pipeline.width, pipeline.height, 0, -1000.0, 1000.0);
ProjectOrtho(pipeline, 0, pipeline.width, pipeline.height, 0, -1000.0, 1000.0);
}
else
{
this.renderer.setContext(this.context);
renderer.setContext(this.context);
this.batchList(entries, x, y, alpha, tint);
this.renderer.setContext();
renderer.setContext();
}
this.dirty = true;
@ -787,20 +808,20 @@ var RenderTexture = new Class({
/**
* Draws the Texture Frame to the Render Texture at the given position.
*
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
*
* ```javascript
* var rt = this.add.renderTexture(0, 0, 800, 600);
* rt.drawFrame(key, frame);
* ```
*
*
* You can optionally provide a position, alpha and tint value to apply to the frame
* before it is drawn.
*
*
* Calling this method will cause a batch flush, so if you've got a stack of things to draw
* in a tight loop, try using the `draw` method instead.
*
*
* If you need to draw a Sprite to this Render Texture, use the `draw` method instead.
*
* @method Phaser.GameObjects.RenderTexture#drawFrame
@ -831,36 +852,40 @@ var RenderTexture = new Class({
}
var gl = this.gl;
var camera = this.camera;
var renderer = this.renderer;
var textureFrame = this.textureManager.getFrame(key, frame);
if (textureFrame)
{
this.camera.preRender(1, 1);
camera.preRender(1, 1);
if (gl)
{
var cx = this.camera._cx;
var cy = this.camera._cy;
var cw = this.camera._cw;
var ch = this.camera._ch;
this.renderer.setFramebuffer(this.framebuffer, false);
this.renderer.pushScissor(cx, cy, cw, ch, ch);
var pipeline = this.pipeline;
pipeline.projOrtho(0, this.texture.width, 0, this.texture.height, -1000.0, 1000.0);
pipeline.batchTextureFrame(textureFrame, x + this.frame.cutX, y + this.frame.cutY, tint, alpha, this.camera.matrix, null);
pipeline.flush();
this.renderer.setFramebuffer(null, false);
var cx = camera._cx;
var cy = camera._cy;
var cw = camera._cw;
var ch = camera._ch;
this.renderer.popScissor();
pipeline.projOrtho(0, pipeline.width, pipeline.height, 0, -1000.0, 1000.0);
renderer.resetTextures(true);
renderer.setFramebuffer(this.framebuffer, false);
renderer.pushScissor(cx, cy, cw, ch, ch);
var pipeline = this.pipeline;
ProjectOrtho(pipeline, 0, this.texture.width, 0, this.texture.height, -1000.0, 1000.0);
pipeline.batchTextureFrame(textureFrame, x + this.frame.cutX, y + this.frame.cutY, tint, alpha, camera.matrix, null);
pipeline.flush();
renderer.setFramebuffer(null, false);
renderer.popScissor();
ProjectOrtho(pipeline, 0, pipeline.width, pipeline.height, 0, -1000.0, 1000.0);
}
else
{
@ -983,7 +1008,7 @@ var RenderTexture = new Class({
}
gameObject.setPosition(x + this.frame.cutX, y + this.frame.cutY);
gameObject.renderWebGL(this.renderer, gameObject, 0, this.camera, null);
gameObject.setPosition(prevX, prevY);
@ -1080,9 +1105,9 @@ var RenderTexture = new Class({
var ctx = this.context;
var cd = textureFrame.canvasData;
var source = textureFrame.source.image;
var matrix = this.camera.matrix;
ctx.globalAlpha = this.globalAlpha;
ctx.setTransform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
@ -1093,11 +1118,11 @@ var RenderTexture = new Class({
/**
* Takes a snapshot of the given area of this Render Texture.
*
*
* The snapshot is taken immediately.
*
*
* To capture the whole Render Texture see the `snapshot` method. To capture a specific pixel, see `snapshotPixel`.
*
*
* Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView.
* It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it,
* which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process,
@ -1132,11 +1157,11 @@ var RenderTexture = new Class({
/**
* Takes a snapshot of the whole of this Render Texture.
*
*
* The snapshot is taken immediately.
*
*
* To capture just a portion of the Render Texture see the `snapshotArea` method. To capture a specific pixel, see `snapshotPixel`.
*
*
* Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView.
* It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it,
* which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process,
@ -1167,11 +1192,11 @@ var RenderTexture = new Class({
/**
* Takes a snapshot of the given pixel from this Render Texture.
*
*
* The snapshot is taken immediately.
*
*
* To capture the whole Render Texture see the `snapshot` method. To capture a specific portion, see `snapshotArea`.
*
*
* Unlike the other two snapshot methods, this one will send your callback a `Color` object containing the color data for
* the requested pixel. It doesn't need to create an internal Canvas or Image object, so is a lot faster to execute,
* using less memory, than the other snapshot methods.

Some files were not shown because too many files have changed in this diff Show more