mirror of
https://github.com/photonstorm/phaser
synced 2024-11-24 13:43:26 +00:00
479 lines
46 KiB
Markdown
479 lines
46 KiB
Markdown
# Phaser - HTML5 Game Framework
|
|
|
|
![Phaser Header](https://phaser.io/images/github/300/phaser-header.png "Phaser 3 Header Banner")
|
|
|
|
Phaser is a fast, free, and fun open source HTML5 game framework that offers WebGL and Canvas rendering across desktop and mobile web browsers. Games can be compiled to iOS, Android and native apps by using 3rd party tools. You can use JavaScript or TypeScript for development.
|
|
|
|
Phaser is available in two versions: Phaser 3 and [Phaser CE - The Community Edition](https://github.com/photonstorm/phaser-ce). Phaser CE is a community-lead continuation of the Phaser 2 codebase and is hosted on a separate repo. Phaser 3 is the next generation of Phaser.
|
|
|
|
Along with the fantastic open source community, Phaser is actively developed and maintained by [Photon Storm](http://www.photonstorm.com). As a result of rapid support, and a developer friendly API, Phaser is currently one of the [most starred](https://github.com/collections/javascript-game-engines) game frameworks on GitHub.
|
|
|
|
Thousands of developers from indie and multi-national digital agencies, and universities worldwide use Phaser. You can take a look at their incredible [games](https://phaser.io/games/).
|
|
|
|
**Visit:** The [Phaser website](https://phaser.io) and follow on [Twitter](https://twitter.com/phaser_) (#phaserjs)<br />
|
|
**Learn:** [API Docs](https://github.com/photonstorm/phaser3-docs), [Support Forum][forum] and [StackOverflow](https://stackoverflow.com/questions/tagged/phaser-framework)<br />
|
|
**Code:** 700+ [Examples](https://labs.phaser.io) (source available in this [repo][examples])<br />
|
|
**Read:** The [Phaser World](#newsletter) Newsletter<br />
|
|
**Chat:** [Slack](https://phaser.io/community/slack) and [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 />
|
|
|
|
Grab the source and join the fun!
|
|
|
|
![What's New](https://phaser.io/images/github/div-whats-new.png "What's New")
|
|
|
|
<div align="center"><img src="https://phaser.io/images/github/news.jpg"></div>
|
|
|
|
> 13th June 2018
|
|
|
|
I'm pleased to announce that Phaser 3.10.0 is now available. This release represents just under a month's worth of work and is a huge version for us. It introduces a lot of significant new features into v3, including multi-touch support, custom cursors, pixel perfect detection, Scene isolated input events, new Input plugins, a brand new Gamepad system and plenty more. There are big changes in Arcade Physics too, with a new fixed timestep option, angular damping, speed improvements, support for time scaling across your whole physics simulation and, yes, even more. The Data Manager too has been given a real shot in the arm, and there are subtle but important changes to the Scene flow and Loader interactions.
|
|
|
|
There are, of course, plenty of bug fixes and updates too. I'd urge you to carefully read the Change Log, especially if upgrading from an earlier version in an existing project. Hundreds more areas have been covered with documentation too. An on-going battle which we're winning, albeit slowly.
|
|
|
|
3.10 is a huge release and represents tireless effort on my part to get it into this shape. My aim has always been to continue the mission of enhancing Phaser 3 as quickly as I can. It means releasing significant updates in relatively short periods of time. But it also means I'm jumping on bug reports as quickly as I can, keeping the issues list total nice and low (the vast majority of the items in there are feature requests now!) - a massive thank-you to all of you who support Phaser on Patreon and PayPal. It's your support that allows me to work on this full-time, to the benefit of everyone.
|
|
|
|
As always, please check out the [Change Log](#changelog) for comprehensive details about what recent versions contain.
|
|
|
|
**About Phaser 3**
|
|
|
|
After 1.5 years in the making, tens of thousands of lines of code, hundreds of examples and countless hours of relentless work: Phaser 3 is finally out. It has been a real labor of love and then some!
|
|
|
|
Please understand this is a bleeding-edge and brand new release. There are features we've had to leave out, areas of the documentation that need completing and so many cool new things we wanted to add. But we had to draw a line in the sand somewhere and 3.0.0 represents that.
|
|
|
|
For us this is just the start of a new chapter in Phaser's life. We will be jumping on bug reports as quickly as we can and releasing new versions rapidly. We've structured v3 in such a way that we can push out point releases as fast as needed.
|
|
|
|
We publish our [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 us and the wider Phaser community.
|
|
|
|
You can also follow Phaser on [Twitter](https://twitter.com/phaser_) and chat with fellow Phaser devs in our [Slack](https://phaser.io/community/slack) and [Discord](https://phaser.io/community/discord) channels.
|
|
|
|
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.
|
|
|
|
Happy coding everyone!
|
|
|
|
Cheers,
|
|
|
|
Rich - [@photonstorm](https://twitter.com/photonstorm)
|
|
|
|
![boogie](https://www.phaser.io/images/spacedancer.gif)
|
|
|
|
![Support Phaser](https://phaser.io/images/github/div-support-phaser.png "Support Phaser")
|
|
|
|
Developing Phaser takes a lot of time, effort and money. There are monthly running costs as well as countless hours of development time, community support, and assistance resolving issues.
|
|
|
|
If you have found Phaser useful in your development life or have made income as a result of it please support our work via:
|
|
|
|
* A monthly contribution on [Patreon](https://www.patreon.com/photonstorm).
|
|
* A [one-off donation](https://phaser.io/community/donate) with PayPal.
|
|
* Purchase any of our [plugins or books](https://phaser.io/shop).
|
|
|
|
It all helps and genuinely contributes towards future development.
|
|
|
|
Extra special thanks to our top-tier sponsors: [Orange Games](http://orangegames.com) and [CrossInstall](https://crossinstall.com).
|
|
|
|
![Sponsors](https://phaser.io/images/github/patreon-sponsors-2018-1.png "Top Patreon 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 120 previous editions can be found on our [Back Issues](https://phaser.io/community/backissues) page.
|
|
|
|
![Download Phaser](https://phaser.io/images/github/div-download.png "Download Phaser")
|
|
<a name="download"></a>
|
|
|
|
Phaser 3 is available via GitHub, npm and CDNs:
|
|
|
|
* Clone the git repository via [https][clone-http], [ssh][clone-ssh] or with the Github [Windows][clone-ghwin] or [Mac][clone-ghmac] clients.
|
|
* Download as [zip](https://github.com/photonstorm/phaser/archive/master.zip)
|
|
* Download the build files: [phaser.js][get-js] and [phaser.min.js][get-minjs]
|
|
|
|
### NPM
|
|
|
|
Install via [npm](https://www.npmjs.com):
|
|
|
|
```bash
|
|
npm install phaser
|
|
```
|
|
|
|
### CDN
|
|
|
|
[![](https://data.jsdelivr.com/v1/package/gh/photonstorm/phaser/badge)](https://www.jsdelivr.com/package/gh/photonstorm/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.10.1/dist/phaser.js"></script>
|
|
```
|
|
|
|
or the minified version:
|
|
|
|
```html
|
|
<script src="//cdn.jsdelivr.net/npm/phaser@3.10.1/dist/phaser.min.js"></script>
|
|
```
|
|
|
|
### API Documentation
|
|
|
|
1. Go to https://photonstorm.github.io/phaser3-docs/index.html to read the docs online. Use the drop-down menus at the top to navigate the name spaces, classes and Game Objects lists. If you wish to run the docs locally you can ...
|
|
2. Checkout the [phaser3-docs](https://github.com/photonstorm/phaser3-docs) repository and then read the documentation by pointing your browser to the local `docs/` folder, and again selecting from the Classes or Namespaces links at the top of the page.
|
|
|
|
The documentation for Phaser 3 is an on-going project. Please help us by searching the Phaser code for any instance of the string `[description]` and then replacing it with some documentation.
|
|
|
|
### TypeScript Definitions
|
|
|
|
[TypeScript Definitions](https://github.com/photonstorm/phaser3-docs/tree/master/typescript) are now available.
|
|
|
|
They are automatically generated from the jsdoc comments in the Phaser source code. If you wish to help refine them then you must edit the Phaser jsdoc blocks directly. You can find more details, including the source to the conversion tool we wrote in the Docs repo.
|
|
|
|
As soon as we're happy with the accuracy of the TS defs we'll merge them into the main repo, for now, please download them from the docs repo, linked above, and add them to your project. When we release new versions of Phaser we publish new TS defs too.
|
|
|
|
### Webpack
|
|
|
|
We use Webpack to build Phaser and we take advantage of its conditional build flag feature to handle renderer swapping. If you wish to use Webpack with Phaser then please use our [Phaser 3 Project Template](https://github.com/photonstorm/phaser3-project-template) as it's already set-up to handle the build conditions Phaser needs. Recent changes to our build steps mean you should now be able to us any other packager, like Parcel, without any config changes.
|
|
|
|
### License
|
|
|
|
Phaser is released under the [MIT License](https://opensource.org/licenses/MIT).
|
|
|
|
![Getting Started](https://phaser.io/images/github/div-getting-started.png "Getting Started")
|
|
<a name="getting-started"></a>
|
|
|
|
<img src="https://phaser.io/images/github/learn.jpg" align="right">
|
|
|
|
Phaser 3 is so new the "paint is still wet", but tutorials and guides are starting to come out!
|
|
|
|
* [Getting Started with Phaser 3](https://phaser.io/tutorials/getting-started-phaser3) (useful if you are completely new to Phaser)
|
|
* [Making your first Phaser 3 Game](https://phaser.io/tutorials/making-your-first-phaser-3-game)
|
|
* [Phaser 3 Bootstrap and Platformer Example](https://phaser.io/news/2018/02/phaser-3-bootstrap-platformer)
|
|
|
|
Also, please subscribe to the [Phaser World](https://phaser.io/community/newsletter) newsletter for details about new tutorials as they are published.
|
|
|
|
### Source Code Examples
|
|
|
|
During our development of Phaser 3, we created hundreds of examples with the full source code and assets. Until these examples are fully integrated into the Phaser website, you can browse them on [Phaser 3 Labs](https://labs.phaser.io), or clone the [examples repo][examples]. We are constantly adding to and refining these examples.
|
|
|
|
### Create Your First Phaser 3 Example
|
|
|
|
Create an `index.html` page locally and paste the following code into it:
|
|
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<script src="https://labs.phaser.io/build/phaser-arcade-physics.min.js"></script>
|
|
</head>
|
|
<body>
|
|
|
|
<script></script>
|
|
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
This is a standard empty webpage. You'll notice there's a script tag that is pulling in a build of Phaser 3, but otherwise this webpage doesn't do anything yet. Now let's set-up the game config. Paste the following between the `<script></script>` tags:
|
|
|
|
```javascript
|
|
var config = {
|
|
type: Phaser.AUTO,
|
|
width: 800,
|
|
height: 600,
|
|
physics: {
|
|
default: 'arcade',
|
|
arcade: {
|
|
gravity: { y: 200 }
|
|
}
|
|
},
|
|
scene: {
|
|
preload: preload,
|
|
create: create
|
|
}
|
|
};
|
|
```
|
|
|
|
`config` is a pretty standard Phaser 3 Game Configuration object. We tell `config` to use the WebGL renderer if it can, set the canvas to a size of 800x600 pixels, enable Arcade Physics, and finally call the `preload` and `create` functions. `preload` and `create` have not been implemented yet, so if you run this JavaScript code, you will have an error. Add the following after `config`:
|
|
|
|
```javascript
|
|
var game = new Phaser.Game(config);
|
|
|
|
function preload ()
|
|
{
|
|
this.load.setBaseURL('http://labs.phaser.io');
|
|
|
|
this.load.image('sky', 'assets/skies/space3.png');
|
|
this.load.image('logo', 'assets/sprites/phaser3-logo.png');
|
|
this.load.image('red', 'assets/particles/red.png');
|
|
}
|
|
|
|
function create ()
|
|
{
|
|
}
|
|
```
|
|
|
|
`game` is a Phaser Game instance that uses our configuration object `config`. We also add function definitions for `preload` and `create`. The `preload` function helps you easily load assets into your game. In `preload`, we set the Base URL to be the Phaser server and load 3 PNG files.
|
|
|
|
The `create` function is empty, so it's time to fill it in:
|
|
|
|
```javascript
|
|
function create ()
|
|
{
|
|
this.add.image(400, 300, 'sky');
|
|
|
|
var particles = this.add.particles('red');
|
|
|
|
var emitter = particles.createEmitter({
|
|
speed: 100,
|
|
scale: { start: 1, end: 0 },
|
|
blendMode: 'ADD'
|
|
});
|
|
|
|
var logo = this.physics.add.image(400, 100, 'logo');
|
|
|
|
logo.setVelocity(100, 200);
|
|
logo.setBounce(1, 1);
|
|
logo.setCollideWorldBounds(true);
|
|
|
|
emitter.startFollow(logo);
|
|
}
|
|
```
|
|
|
|
Here we add a sky image into the game and create a Particle Emitter. The `scale` value means that the particles will initially be large and will shrink to nothing as their lifespan progresses.
|
|
|
|
After creating the `emitter`, we add a logo image called `logo`. Since `logo` is a Physics Image, `logo` is given a physics body by default. We set some properties for `logo`: velocity, bounce (or restitution), and collision with the world bounds. These properties will make our logo bounce around the screen. Finally, we tell the particle emitter to follow the logo - so as the logo moves, the particles will flow from it.
|
|
|
|
Run it in your browser and you'll see the following:
|
|
|
|
![Phaser 3 Demo](https://phaser.io/images/github/300/sample1.png "Phaser 3 Demo")
|
|
|
|
(Got an error? Here's the [full code](https://gist.github.com/photonstorm/46cb8fb4b19fc7717dcad514cdcec064))
|
|
|
|
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.
|
|
|
|
![Building Phaser](https://phaser.io/images/github/div-building-phaser.png "Building Phaser")
|
|
|
|
There are both plain and minified compiled versions of Phaser in the `dist` folder of the repository. The plain version is for use during development, and the minified version is for production use. You can also create your own builds.
|
|
|
|
### Custom Builds
|
|
|
|
Phaser 3 is built using Webpack and we take advantage of the Webpack definePlugin feature to allow for conditional building of the Canvas and WebGL renderers. As of Phaser 3.7 we have updated our webpack config to make our source far easier to consume in other package managers like Parcel and Electron. Please look our webpack config files to get an idea of the settings we use.
|
|
|
|
### Building from Source
|
|
|
|
If you wish to build Phaser 3 from source, ensure you have the required packages by cloning the repository and then running `npm install`.
|
|
|
|
You can then run `webpack` to create a development build in the `build` folder which includes source maps for local testing. You can also `npm run dist` to create a minified packaged build in the `dist` folder. For a list of all commands available use `npm run help`.
|
|
|
|
![Change Log](https://phaser.io/images/github/div-change-log.png "Change Log")
|
|
<a name="changelog"></a>
|
|
|
|
# Change Log
|
|
|
|
## Version 3.10.1 - Hayashi - 13th June 2018
|
|
|
|
### Bug Fixes
|
|
|
|
* The InputManager would only create 1 Pointer, even if Touch input was enabled in the config, which meant you couldn't use touch events unless you first called `addPointer` or specified one in the config. Now, it Touch is enabled in the config, it'll always create 2 pointers by default.
|
|
|
|
## Version 3.10.0 - Hayashi - 13th June 2018
|
|
|
|
### Input System New Features + Updates
|
|
|
|
* All Input classes are now covered 100% by JSDocs.
|
|
* The Input Manager and Input Plugin have been updated to support multiple simultaneous Pointers. Before, only one active pointer (mouse or touch) was supported. Now, you can have as many active pointers as you need, allowing for complex multi-touch games. These are stored in the Input Manager `pointers` array.
|
|
* `addPointer` allows you to add one, or more, new pointers to the Input Manager. There is no hard-coded limit to the amount you can have, although realistically you should never need more than 10. This method is available on both the Input Manager and Plugin, allowing you to use `this.input.addPointer` from within your game code.
|
|
* InputManager `pointersTotal` contains the total number of active pointers, which can be set in the Game Config using the `input.activePointers` property. Phaser will create 2 pointers on start unless a different value is given in the config, or you can add them at run-time.
|
|
* `mousePointer` is a new property that is specifically allocated for mouse use only. This is perfect for desktop only games but should be ignored if you're creating a mouse + touch game (use activePointer instead).
|
|
* `activePointer` will now reflect the most recently active pointer on the game, which is considered as being the pointer to have interacted with the game canvas most recently.
|
|
* The InputManager and InputPlugin have three new methods: `addUpCallback`, `addDownCallback` and `addMoveCallback`. These methods allow you to add callbacks to be invoked whenever native DOM mouse or touch events are received. Callbacks passed to this method are invoked _immediately_ when the DOM event happens, within the scope of the DOM event handler. Therefore, they are considered as 'native' from the perspective of the browser. This means they can be used for tasks such as opening new browser windows, or anything which explicitly requires user input to activate. However, as a result of this, they come with their own risks, and as such should not be used for general game input, but instead be reserved for special circumstances. The callbacks can be set as `isOnce` so you can control if the callback is called once then removed, or every time the DOM event occurs.
|
|
* Pointer has two new properties `worldX` and `worldY` which contain the position of the Pointer, translated into the coordinate space of the most recent Camera it interacted with.
|
|
* When checking to see if a Pointer has interacted with any objects it will now iterate through the Camera list. Previously, it would only check against the top-most Camera in the list, but now if the top-most camera doesn't return anything, it will move to the next camera and so on. This also addresses #3631 (thanks @samid737)
|
|
* `InputManager.dirty` is a new internal property that reflects if any of the Pointers have updated this frame.
|
|
* `InputManager.update` now uses constants internally for the event type checking, rather than string-based like before.
|
|
* `InputManager.startPointer` is a new internal method, called automatically by the update loop, that handles touch start events.
|
|
* `InputManager.updatePointer` is a new internal method, called automatically by the update loop, that handles touch move events.
|
|
* `InputManager.stopPointer` is a new internal method, called automatically by the update loop, that handles touch end events.
|
|
* `InputManager.hitTest` has had its arguments changed. It no longer takes x/y properties as the first two arguments, but instead takes a Pointer object (from which the x/y coordinates are extracted).
|
|
* `TouchManager.handler` has been removed as it's no longer used internally.
|
|
* `TouchManager.onTouchStart`, `onTouchMove` and `onTouchEnd` are the new DOM Touch Event handlers. They pass the events on to the InputManagers `queueTouchStart`, `queueTouchMove` and `queueTouchEnd` methods respectively.
|
|
* `MouseManager.handler` has been removed as it's no longer used internally.
|
|
* `MouseManager.onMouseDown`, `onMouseMove` and `onMouseUp` are the new DOM Mouse Event handlers. They pass the events on to the InputManagers `queueMouseDown`, `queueMouseMove` and `queueMouseUp` methods respectively.
|
|
* Setting `enabled` to false on either the TouchManager, MouseManager or KeyboardManager will prevent it from handling any native DOM events until you set it back again.
|
|
* InputPlugin has the following new read-only properties: `mousePointer`, `pointer1`, `pointer2`, `pointer3`, `pointer4`, `pointer5`, `pointer6`, `pointer7`, `pointer8`, `pointer9` and `pointer10`. Most of these will be undefined unless you call `addPointer` first, or set the active pointers quantity in your Game Config.
|
|
* InputManager has a new method `transformPointer` which will set the transformed x and y properties of a Pointer in one call, rather than the 2 calls it took before. This is now used by all Pointer event handlers.
|
|
* InputPlugin has a new method `makePixelPerfect` which allows you to specify a texture-based Game Object as being pixel perfect when performing all input checks against it. You use it like this: `this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect())`, or the easier: `setInteractive({ pixelPerfect: true })` - you can also pass or set an optional alpha tolerance level. See the method docs for full details and the new examples to see it in action. Note that as a pointer interacts with the Game Object it will constantly poll the texture, extracting a single pixel from the given coordinates and checking its color values. This is an expensive process, so should only be enabled on Game Objects that really need it.
|
|
|
|
### Input - Custom Cursors
|
|
|
|
* You can now set a custom cursor for your game via `this.input.setDefaultCursor()`. This will take any valid CSS cursor string, including URLs to cursor image files.
|
|
* You can now set a custom cursor for specific Game Objects. This will take any valid CSS cursor string, including URLs to cursor image files, and is used when-ever a pointer is over that Game Object. For example, to have a hand cursor appear when over a button Sprite, you can do: `button.input.cursor = 'pointer'`, or to have a help cursor appear: `button.input.cursor = 'help'`, or to have a custom image: `button.input.cursor = 'url(assets/cursors/sword.cur), pointer'`.
|
|
* You can also set a custom cursor in the new Input Configuration Object. To use the `pointer` (hand cursor) there is a new short-cut: `setInteractive({ useHandCursor: true })`. To use anything else: `setInteractive({ cursor: CSSString })` where `CSSString` is any valid CSS for setting a cursor.
|
|
* Please be aware of limitations when it comes to image based cursors between browsers. It's up to you to find a suitable format and size that fits the browsers you wish to support (note: virtually all modern browsers no longer support animated CSS cursors.)
|
|
|
|
### Input - Configuration Objects
|
|
|
|
* The `setInteractive` method can now take an Input Configuration object as its only argument. This allows you to set multiple input related properties in a single call, i.e.: `setInteractive({ draggable: true, pixelPerfect: true })`. The available properties are:
|
|
* `hitArea` - The object / shape to use as the Hit Area. If not given it will try to create a Rectangle based on the texture frame.
|
|
* `hitAreaCallback` - The callback that determines if the pointer is within the Hit Area shape or not.
|
|
* `draggable` - If `true` the Interactive Object will be set to be draggable and emit drag events.
|
|
* `dropZone` - If `true` the Interactive Object will be set to be a drop zone for draggable objects.
|
|
* `useHandCursor` - If `true` the Interactive Object will set the `pointer` hand cursor when a pointer is over it. This is a short-cut for setting `cursor: 'pointer'`.
|
|
* `cursor` - The CSS string to be used when the cursor is over this Interactive Object.
|
|
* `pixelPerfect` - If `true` the a pixel perfect function will be set for the hit area callback. Only works with texture based Game Objects.
|
|
* `alphaTolerance` - If `pixelPerfect` is set, this is the alpha tolerance threshold value used in the callback.
|
|
|
|
### Input - Keyboard Manager Updates
|
|
|
|
* The `KeyboardManager` class has been removed. It has been replaced with `KeyboardPlugin` which is now an Input level plugin, that registers itself with the new `InputPluginCache`. The Input Plugin class (which belongs to a Scene) will now automatically inject registered plugins into itself on boot. Every Scene has its own instance of the Input Plugin (if enabled in the scene plugins), which in turn has its own instance of the KeyboardPlugin. The `InputManager` no longer has any reference to the Keyboard class at all. The benefits of this are two-fold: First, it allows you to now entirely exclude all of the keyboard classes from a custom build, saving a lot of space if not required. Secondly, it means that the Scenes themselves are now responsible for keyboard events, where-as before they were entirely global. This means a Scene can be paused and stop processing keyboard events, and stop having its Key objects updated, while another Scene can still carry on doing this. It also prevents key related callbacks in sleeping Scenes from being fired (which resolves issue #3733, thanks @JoeMoov2)
|
|
* `KeyboardManager.handler` has been renamed to `onKeyHandler`.
|
|
* The `KeyboardManager.captures` property has been removed as it can be more effectively handled by polling the `keys` object instead.
|
|
* The Keyboard Manager will no longer process key down or up events if its `enabled` property is set to false, or if the Scene to which it belongs is not active.
|
|
* The Keyboard Manager will now call `event.preventDefault` on the native DOM event as long as the Key exists in the keys array and has its `preventDefault` property set to `true` (which is the default). This means you can now control specifically which key prevents default on the browser, where-as before every key added did so.
|
|
* KeyboardManager `addKeyCapture` and `removeKeyCapture` have been removed as you now control which keys prevent capture by using the `addKey` or `addKeys` methods (see entry above). The act of creating a Key is now enough to enable capture of it and can be toggled (at run-time) on a per-Key basis.
|
|
* `KeyboardManager.addKeys` can now take either an object, or key codes, or a comma-separated string as its input. This means you can now do: `keyboard.addKeys('W,S,A,D')` and get an object back with the properties WSAD mapped to the relevant Key objects.
|
|
* `KeyboardManager.addKey` can now take either a Key object, a string, such as `A` or `SPACE`, or a key code value.
|
|
* `KeyboardManager.removeKey` can now take either a Key object, a string, such as `A` or `SPACE`, or a key code value.
|
|
|
|
### Input - Gamepad Manager Updates
|
|
|
|
* The `GamepadManager` class has been removed. It has been replaced with `GamepadPlugin` which is now an Input level plugin, that registers itself with the new `InputPluginCache`. The Input Plugin class (which belongs to a Scene) will now automatically inject the registered plugins into itself on boot. Every Scene has its own instance of the Input Plugin (if enabled in the scene plugins), which in turn has its own instance of the GamepadPlugin. The `InputManager` no longer has any reference to the Gamepad class at all. The benefits of this are two-fold: First, it allows you to now entirely exclude all of the gamepad classes from a custom build, saving a lot of space if not required. Secondly, it means that the Scenes themselves are now responsible for gamepad events, where-as before they were entirely global. This means a Scene can be paused and stop processing gamepad events, and stop having its Gamepad objects updated, while another Scene can still carry on doing this. It also prevents gamepad related callbacks in sleeping Scenes from being fired.
|
|
* The Gamepad Plugin has been rewritten from scratch. It now offers a lot more features and far easier access to the Gamepads and their properties. You can now access the first 4 gamepads connected to the browser via the `pad1` to `pad4` properties, meaning you can do: `this.input.gamepad.pad1` for direct access to a pad once it's connected.
|
|
* The Gamepad class has also been rewritten from scratch. It will no longer create Buttons or Axes dynamically, instead doing so on instantiation.
|
|
* The Gamepad class now has a bunch of new properties for easy access to the various standard mapping buttons. These include `left`, `right`, `up`, `down` for directions, `A`, `Y`, `X` and `B` for buttons, `L1`, `L2`, `R1` and `R2` for shoulder buttons, and `leftStick` and `rightStick` for the axis sticks. You can still use `Gamepad.getButtonValue()` to get the value from a button and `Gamepad.getButtonTotal()` to get the total number of buttons available on the pad.
|
|
* `Gamepad.getAxisTotal` and `Gamepad.getAxisValue` will return the total number of axis, and an axis value, accordingly.
|
|
* `Gamepad.setAxisThreshold` will now let you set the threshold across all axis of a Gamepad in one call.
|
|
* The Gamepad `Button` objects will now emit 2 events, one from the button itself and another from the Gamepad. This means you can listen for button events in 3 ways: 1) By directly polling the button value in an update loop, 2) Listening for events on the Gamepad Plugin: `this.input.gamepad.on('down')`, or 3) By listening for events on the Gamepad itself: `gamepadReference.on('down')`.
|
|
|
|
### Arcade Physics New Features + Updates
|
|
|
|
* Arcade Physics now uses a fixed time-step for all internal calculations. There is a new `fps` config value and property (defaults to 60fps), which you can change at run-time using the `setFPS` method. The core update loop has been recoded so that it steps based entirely on the given frame rate, and not the wall-clock or game step delta. This fixed time step allows for a straightforward implementation of a deterministic game state. Meaning you can now set the fps rate to a high value such as 240, regardless of the browser update speed (it will simply perform more physics steps per game step). This is handy if you want to increase the accuracy of the simulation in certain cases.
|
|
* You can also optionally call the `step` function directly, to manually advance the simulation.
|
|
* There is a new property `timeScale` which will scale all time-step calculations at run-time, allowing you to speed-up or slow-down your simulation at will, without adjusting the frame rate.
|
|
* You can now disable the use of the RTree for dynamic bodies via the config property `useTree`. In certain situations, i.e. densely packed worlds, this may give better performance. Static bodies will always use an RTree.
|
|
* `collideSpriteVsGroup` has been rewritten. If you are using an RTree it now uses the results directly from the tree search, instead of iterating all children in the Group, which dramatically reduces the work it does. If you have disabled the RTree it performs a brute-force O(N2) Sprite vs. Group iteration sweep. We tested multiple axis sorting variants but the cost of the array allocation and/or sorting, with large amounts of bodies (10,000+), far outweighed the simple math involved in the separation logic.
|
|
* `Body.useDamping` is a new boolean property that allows you to use a damping effect for drag, rather than the default linear deceleration. This gives much better results if you need smooth deceleration across both axis, such as the way the ship slows down in the game Asteroids, without the tell-tale axis drift associated with linear drag.
|
|
* `GetOverlapX` and `GetOverlapY` now use the calculated delta values, not the deltaX/Y methods.
|
|
* `collideSpriteVsGroup` aborts early if the Sprite body has been disabled.
|
|
* `updateMotion` has a new argument `delta` which should typically be a fixed-time delta value.
|
|
* `intersects` has been restructured to prioritize rect vs. rect checks.
|
|
* Body `update` and `postUpdate` have been recoded to handle the new fixed time-step system in place. `update` now takes a new argument, delta, which is used internally for calculations.
|
|
* `Body.dirty` has been removed as a property as it's no longer used internally.
|
|
* `Body.deltaAbsX` and `deltaAbsY` now return the cached absolute delta value from the previous update, and no longer calculate it during the actual call.
|
|
* `World.enable` has been recoded to remove all the `hasOwnProperty` checks and streamline the internal flow.
|
|
* `World.disable` has been recoded to remove all the `hasOwnProperty` checks and streamline the internal flow.
|
|
* `World.add` is a new method that adds an existing body to the simulation and `enableBody` now passes its newly created bodies to this method.
|
|
* `World.disableGameObjectBody` has been removed as it duplicated what the `disable` method did.
|
|
* There is a new internal flow with regard to the creation and disabling of bodies. Calling `World.enable` will pass the objects to `enableBody`, which will create a new Body object, if required, and finally pass it to `add`. `World.disable` does the same, but removes the bodies from the simulation. It passes the bodies to `disableBody`, which in turn passes it to `remove`. Both of these work for single objects, an array of objects, Groups or even arrays of Groups.
|
|
* `World.computeAngularVelocity` is a new method that specifically calculates the angular velocity of a Body.
|
|
* `World.computeVelocity` has had its signature changed. Rather than taking a bunch of arguments all it now takes is a Body and a delta value. Internally it now calculates both the x and y velocity components together in the same single call, where-as before it was split into two calls and multiple assignments.
|
|
* `World.computeVelocity` no longer returns the new velocities, they are now set directly on the body within the method.
|
|
* `World.computeVelocity` has been recoded to use Fuzzy Greater Than and Less Than calls when applying drag to a previously accelerated body. Using a fuzzy epsilon allows us to mitigate the ping-pong issue, where a decelerating body would constantly flip between a small negative and positive velocity value and never come to an actual rest.
|
|
* `World.computeVelocity` now checks the `Body.useDamping` property to perform either linear deceleration or damping on the Body.
|
|
* `World.updateMotion` has changed to call the new `computeAngularVelocity` and `computeVelocity` methods.
|
|
* Bodies set to bounce would eventually run out of velocity and stop. This has been fixed as part of the refactoring of the time step and compute velocity updates. Fix #3593 (thanks @helmi77)
|
|
* If a Body collides with a Static Body it will now set the `blocked` properties accordingly (before it only set the `touching` properties.) This means you can now use checks like `Body.onFloor()` when traversing static bodies (thanks @fariazz)
|
|
|
|
### Data Manager New Features and Updates
|
|
|
|
* You can now access anything set in the DataManager using the new `values` property. For example, if you set a new value such as this: `data.set('gold', 50)` you can now access it via: `data.values.gold`, where it is treated as a normal property, allowing you to use it in conditional evaluations `if (data.values.level === 2)`, or modify it: `data.values.gold += 50`.
|
|
* Each time a value is updated it emits a `changedata` event, regardless if it is changed via the `set` method, or the new `values` approach.
|
|
* Each time a value is updated it emits a new event named after the value. For example, if the value was called `PlayerLives`, it will emit the event `changedata_PlayerLives`. This happens regardless if it is changed via the `set` method, or the new `values` approach.
|
|
* The `set` method can now take an object containing key value pairs as the first argument. This means you can now set a bunch of values all at once, i.e: `data.set({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 })`.
|
|
* The `get` method can now take an array of keys, and will return an array of matching values. This is handy for array destructuring in ES6.
|
|
* The `remove` method can now take an array of keys, and will remove all matching values, emitting the `removedata` event for each.
|
|
* The order of events has been updated. When a value is first set, and doesn't already exist in the Data Manager, it will emit a `setdata` event. If a value is set that already exists, it instead emits a `changedata` and related `changedata_key` event. Setting a new value no longer emits both events.
|
|
* The `resetFunction` function has been removed from the `changedata` event arguments. Previously this was used to allow you to stop a value being updated by calling the reset function instead. However, it created brand new anonymous functions every single time a value was updated. As you can now access stored data via the `values` property you can use this for much easier conditional checks and sets.
|
|
* The `blockSet` property has been removed as it's no longer used internally.
|
|
|
|
### Loader and Scene Updates
|
|
|
|
* Internally, the Loader has changed slightly. Rather than have each file cause the new batch to load, an `update` method is polled every frame, which does the same job instead. This avoids load-time race conditions where pre-populated files would trigger loads part way during an existing load, fixing #3705 in the process (thanks @the-simian)
|
|
* The Scene Manager has been updated so that it will call Scene.Systems.step during the `init`, `preload` and `create` phase of your Scene. This means that any plugins, or custom code, written to use the Scene Systems `preupdate`, `update` or `postupdate` events will need to be aware that these are now fired from `init` onwards, not just once `create` has finished.
|
|
* As a result of these two changes, there is a new Systems property called `sceneUpdate`, which is a reference that maps to your `Scene.update` function. During `init`, `preload` and `create` this is always mapped to NOOP. Once `create` has finished it gets re-mapped to your Scene's update function. If your Scene doesn't have one, it remains mapped to NOOP. In practise, this means nothing has changed from before. `Scene.update` never ran until `create` was completed, and it still doesn't. However, because the internal Scene systems are now updating right from `init`, it means that things like the update list and physics systems are fully operational _during_ your Preloader. This allows you to create far more elaborate preloaders than ever before. Although, with great power comes great responsibility, as the onus is now on you to be careful which events you consume (especially input events) during your preloader.
|
|
* Another side-effect of these changes is that Scenes no longer need an 'update' function at all. Previously, if they were missing one, the Scene Manager would inject one into them automatically. It no longer does this.
|
|
|
|
### New Features
|
|
|
|
* `RenderTexture.resize` will allow you to resize the underlying Render Texture to the new dimensions given. Doing this also clears the Render Texture at the same time (thanks @saqsun).
|
|
* `Rectangle.RandomOutside` is a new function that takes two Rectangles, `outer` and `inner`, and returns a random point that falls within the outer rectangle but is always outside of the inner rectangle.
|
|
* The Update List has a new read-only property `length`, making it consistent with the Display List (thanks @samme)
|
|
* The 2D Camera class has two new read-only properties `centerX` and `centerY` which return the coordinates of the center of the viewport, relative to the canvas (thanks @samme)
|
|
* Camera has a new property `visible`. An invisible Camera will skip rendering and input tests of everything it can see. This allows you to create say a mini-cam and then toggle it on and off without needing to re-create it each time.
|
|
* Camera has a new method `setVisible` which toggles its visible property.
|
|
* `CameraManager.fromJSON` will now set the visible property is defined in the config.
|
|
* `ScenePlugin.run` is a new method that will run the given Scene and not change the state of the current Scene at all. If the scene is asleep, it will be woken. If it's paused, it will be resumed. If not running at all, it will be started.
|
|
* `TextureManager.getPixelAlpha` is a new method that will return the alpha value of a pixel from the given texture and frame. It will return `null` if the coordinates were out of bounds, otherwise a value between 0 and 255.
|
|
* `Game.isOver` is a new read-only boolean property that indicates if the mouse pointer is currently over the game canvas or not. It is set by the VisibilityHandler and is only reliable on desktop systems.
|
|
* A new event `Game.mouseout` is dispatched if the mouse leaves the game canvas. You can listen to it from `this.sys.game.events.on('mouseout')` from within a Scene.
|
|
* A new event `Game.mouseover` is dispatched if the mouse enters the game canvas, having previously been outside of it. You can listen to it from `this.sys.game.events.on('mouseover')` from within a Scene.
|
|
* You can now use PhysicsEditor (https://www.codeandweb.com/physicseditor) to create complex Matter.js bodies. Load them as normal JSON and then just pass it to the Matter Sprite as a shape property: `this.matter.add.sprite(x, y, texture, frame, { shape: shapes.banana })` (where `shapes.banana` is one of the exported PhysicsEditor shapes in the JSON you loaded). See the 'physics/matterjs/advanced shape creation.js' example for more details.
|
|
|
|
### Updates
|
|
|
|
* The `ForwardDiffuseLightPipeline`, used by the Lights system, now sets a flag if the Scene doesn't contain any lights. All of the Game Objects now check this flag and don't even bother adding themselves to the batch if there are no lights in the Scene, as they'd never render anyway. This also avoids the ghost-image problem if you swap Scenes to a new Scene with the Light Manager enabled, but no actual lights defined. Fix #3707 (thanks @samvieten).
|
|
* `CameraManager.getCameraBelowPointer` has been renamed to `getCamerasBelowPointer` and it now returns an array of all the cameras below the given pointer, not just the top-most one. The array is sorted so that the top-most camera is at the start of the array.
|
|
* In `TimeStep.step` the `rawDelta` and `delta` values are checked to make sure they are non-negative, which can happen in Chrome when the delta is reset and out of sync with the value passed to Request Animation Frame. Fix #3088 (thanks @Antriel)
|
|
* `Cameras.Controls.Fixed` has been removed. It's was deprecated a few versions ago. Please use `FixedKeyControl` instead.
|
|
* `Cameras.Controls.Smoothed` has been removed. It's was deprecated a few versions ago. Please use `SmoothedKeyControl` instead.
|
|
|
|
### Bug Fixes
|
|
|
|
* The Canvas `RenderTexture.drawImage` method incorrectly set the values of the frame, causing them to appear wrongly scaled in the canvas renderer. Fix #3710 (thanks @saqsun).
|
|
* Fixed `Math.Matrix4.makeRotationAxis()` (thanks @hexus)
|
|
* Fixed an incorrect usage of `Math.abs()` in `Math.Quaternion.calculateW()` (thanks @qxzkjp).
|
|
* Particle Emitter Managers can now be added to Containers (thanks @TadejZupancic)
|
|
* Fixed a method signature issue with the Animation component's `remove()` handler when `Animation`s are removed from the `AnimationManager`. This prevented removed animations from stopping correctly.
|
|
* If you set Phaser to use a pre-existing Canvas element it is no longer re-added to the DOM (thanks @NQNStudios)
|
|
* The `TweenManager.getTweensOf` method has been fixed to remove a potential endless loop should multiple targets be passed in to it (thanks @cyantree)
|
|
* Interactive Objects inside of Containers would still fire their input events even if the Container (or any ancestor) was set to be invisible. Objects now check their ancestor tree during the input cull and now properly skip input events if not visible. Fix #3620 (thanks @NemoStein)
|
|
* Fixed Device.os incorrectly reporting Linux as OS on Android devices (thanks @AleBles)
|
|
|
|
### Examples, Documentation and TypeScript
|
|
|
|
Thanks to the work of @hexus we have now documented all of the Math namespace and made good progress on the Game Objects.
|
|
|
|
I personally have also documented the entire Input system, which was 328 classes, properties and methods to describe, as well as lots of other areas.
|
|
|
|
Please see the complete [Change Log](https://github.com/photonstorm/phaser/blob/master/CHANGELOG.md) for previous releases.
|
|
|
|
Looking for a v2 change? Check out the [Phaser CE Change Log](https://github.com/photonstorm/phaser-ce/blob/master/CHANGELOG.md)
|
|
|
|
![Contributing](https://phaser.io/images/github/div-contributing.png "Contributing")
|
|
<a name="contributing"></a>
|
|
|
|
The [Contributors Guide][contribute] contains full details on how to help with Phaser development. The main points are:
|
|
|
|
- Found a bug? Report it on [GitHub Issues][issues] and include a code sample. Please state which version of Phaser you are using! This is vitally important.
|
|
|
|
- Before submitting a Pull Request run your code through [ES Lint](https://eslint.org/) using our [config](https://github.com/photonstorm/phaser/blob/master/.eslintrc.json) and respect our [Editor Config](https://github.com/photonstorm/phaser/blob/master/.editorconfig).
|
|
|
|
- Before contributing read the [code of conduct](https://github.com/photonstorm/phaser/blob/master/.github/CODE_OF_CONDUCT.md).
|
|
|
|
Written something cool in Phaser? Please tell us about it in the [forum][forum], or email support@phaser.io
|
|
|
|
![Created by](https://phaser.io/images/github/div-created-by.png "Created by")
|
|
|
|
Phaser is a [Photon Storm](http://www.photonstorm.com) production.
|
|
|
|
![storm](https://www.phaser.io/images/github/photonstorm-x2.png)
|
|
|
|
Created by [Richard Davey](mailto:rich@photonstorm.com). Powered by coffee, anime, pixels and love.
|
|
|
|
The Phaser logo and characters are © 2018 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.10.1/phaser.js
|
|
[get-minjs]: https://github.com/photonstorm/phaser/releases/download/v3.10.1/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
|
|
[clone-ghmac]: github-mac://openRepo/https://github.com/photonstorm/phaser
|
|
[phaser]: https://github.com/photonstorm/phaser
|
|
[issues]: https://github.com/photonstorm/phaser/issues
|
|
[examples]: https://github.com/photonstorm/phaser3-examples
|
|
[contribute]: https://github.com/photonstorm/phaser/blob/master/.github/CONTRIBUTING.md
|
|
[forum]: http://www.html5gamedevs.com/forum/33-phaser-3/
|