mirror of
https://github.com/photonstorm/phaser
synced 2025-02-16 22:18:29 +00:00
Merge branch 'master' into arcade_body_custom_bounds
This commit is contained in:
commit
4f4b69123e
1730 changed files with 774189 additions and 482643 deletions
|
@ -8,10 +8,8 @@ src/geom/polygon/Earcut.js
|
|||
src/utils/array/StableSort.js
|
||||
src/utils/object/Extend.js
|
||||
src/structs/RTree.js
|
||||
src/dom/_ScaleManager.js
|
||||
src/dom/VisualBounds.js
|
||||
plugins/spine/src/spine-canvas.js
|
||||
plugins/spine/src/spine-webgl.js
|
||||
plugins/spine/dist/
|
||||
plugins/spine/src/runtimes/
|
||||
webpack.*
|
||||
webpack.config.js
|
||||
webpack.dist.config.js
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
"no-trailing-spaces": [ "error", { "skipBlankLines": true, "ignoreComments": true } ],
|
||||
"no-underscore-dangle": "off",
|
||||
"no-whitespace-before-property": "error",
|
||||
"object-curly-newline": [ "error", { "multiline": true, "minProperties": 0 } ],
|
||||
"object-curly-newline": [ "error", { "multiline": true, "minProperties": 0, "consistent": true } ],
|
||||
"one-var-declaration-per-line": [ "error", "initializations" ],
|
||||
"quote-props": [ "error", "as-needed" ],
|
||||
"quotes": [ "error", "single" ],
|
||||
|
|
4
.github/CONTRIBUTING.md
vendored
4
.github/CONTRIBUTING.md
vendored
|
@ -56,7 +56,7 @@ If your PR is doing little more than changing the Phaser source code into a form
|
|||
|
||||
## I don't really like git / node.js, but I can fix this bug
|
||||
|
||||
That is fine too. While Pull Requests are the best thing in the world for us, they are not the only way to help. You're welcome to post fixes to our forum or even just email them to us. All we ask is that you still adhere to the guidelines presented here re: JSHint, etc.
|
||||
That is fine too. While Pull Requests are the best thing in the world for us, they are not the only way to help. You're welcome to post fixes to our forum or even just email them to us. All we ask is that you still adhere to the guidelines presented here re: ESLint, etc.
|
||||
|
||||
## Code Style Guide
|
||||
|
||||
|
@ -76,5 +76,5 @@ Thanks to Chad for creating the original Pixi.js Contributing file which we adap
|
|||
[1]: http://jsfiddle.net
|
||||
[2]: http://jsbin.com/
|
||||
[3]: http://nodejs.org
|
||||
[4]: http://www.html5gamedevs.com/forum/33-phaser-3/
|
||||
[4]: https://phaser.discourse.group/
|
||||
[5]: https://codepen.io/pen?template=YeEWom "Phaser 3 game template"
|
||||
|
|
5
.github/FUNDING.yml
vendored
Normal file
5
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: photonstorm
|
||||
patreon: photonstorm
|
||||
custom: https://phaser.io/community/donate
|
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -9,7 +9,7 @@ Thank you for taking the time to contribute towards Phaser. Before submitting yo
|
|||
|
||||
1. This repo is for Phaser 3 only. Phaser 2.x issues should be raised in the [Phaser CE](https://github.com/photonstorm/phaser-ce) repo.
|
||||
|
||||
2. This repo should not be used for technical support. If you're struggling to use Phaser then post your question to the [forum](http://www.html5gamedevs.com/forum/33-phaser-3/), [Slack](https://phaser.io/community/slack) or [Discord](https://phaser.io/community/discord) channels. GitHub Issues are for bugs and feature requests only.
|
||||
2. This repo should not be used for technical support. If you're struggling to use Phaser then post your question to the [forum](https://phaser.discourse.group/), [Slack](https://phaser.io/community/slack) or [Discord](https://phaser.io/community/discord) channels. GitHub Issues are for bugs and feature requests only.
|
||||
|
||||
3. Make sure your issue isn't a duplicate, or has already been fixed.
|
||||
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -14,3 +14,5 @@ node_modules/
|
|||
/npm-debug.log
|
||||
build/
|
||||
out/
|
||||
scripts/tsgen/test/bin/
|
||||
scripts/tsgen/test/output.txt
|
||||
|
|
|
@ -12,6 +12,6 @@ env:
|
|||
- TERM=dumb
|
||||
|
||||
script:
|
||||
- yarn install
|
||||
- yarn run lint
|
||||
- yarn run build
|
||||
- npm install
|
||||
- npm run lint
|
||||
- npm run build
|
||||
|
|
1054
CHANGELOG.md
1054
CHANGELOG.md
File diff suppressed because it is too large
Load diff
263
README.md
263
README.md
|
@ -4,15 +4,13 @@
|
|||
|
||||
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 />
|
||||
**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:** [Slack](https://phaser.io/community/slack) and [Discord](https://phaser.io/community/discord)<br />
|
||||
**Extend:** With [Phaser Plugins](https://phaser.io/shop/plugins)<br />
|
||||
|
@ -24,27 +22,19 @@ Grab the source and join the fun!
|
|||
|
||||
<div align="center"><img src="https://phaser.io/images/github/news.jpg"></div>
|
||||
|
||||
> 16th October 2018
|
||||
> 8th August 2019
|
||||
|
||||
Phaser 3.15 is now available. This is slightly ahead of schedule because we needed to get some important performance and iOS input related fixes released, without waiting for new features to be completed first.
|
||||
I'm pleased to announce that Phaser 3.19 is now available. This release includes our brand new Spine plugin. Spine allows you to bring animation to life in your games, offering a dedicated 2D skeletal animation system and workflow. Our plugin makes integration with Phaser seamless and is fully updated for the Spine 3.7 Runtimes with support for WebGL and Canvas renderers. This version will properly batch Spine skeletons where possible, potentially saving hundreds of draw calls. The plugin is fully documented and exports both debug and minified files, suitable for ES6 'importing' or ES5 plugin inclusion. The whole plugin is just 68KB in size (min+gz), or a paltry 57KB if you only need the Canvas renderer! That's a really tiny payload for such a massive feature-set. You can find out more about Spine from the [Esoteric Software website](http://esotericsoftware.com/).
|
||||
|
||||
This means that the new Scale Manager and Spine support have been moved to release 3.16 due towards the end of October. Please read the weekly Dev Logs for details about development.
|
||||
3.19 also introduces a huge overhaul to the Tween system. Tweens now have 100% documentation and we've extended their capabilities significantly. There are lots of new Tween Events to listen for, such as 'COMPLETE' or 'REPEAT' to allow you to trigger actions without needing to create callbacks. Tweens can now tween both 'from' and 'to' a value, with the ability to set a starting value for any tweened property. There are lots of new handy methods and properties, such as `Tween.hasStarted` and a rewrite of the Tween seeking function, so it now allows you to seek to any point in time across a tween. Finally, we've added in the great new 'StaggerBuilder'. This allows you to easily add staggered offsets to a bunch of tween targets, including all kinds of options such as staggering across a grid layout, stagger directions, starting values and a lot more. Please see the docs and examples for more details.
|
||||
|
||||
> 1st October 2018
|
||||
As usual, it doesn't end there, though :) Another very useful feature is `Shader.setRenderToTexture`. This allows you to redirect a shader to its own framebuffer / WebGL Texture instead of to the display list. This allows you to use the output of the shader as an input for another shader, by mapping a sampler2D uniform to it. It also allows you to save the Shader to the Texture Manager, allowing you to use it as a texture for any other texture based Game Object such as a Sprite. Combined with the new `setSampler2DBuffer` method you can now easily chain shaders together, using them as buffers for other shaders.
|
||||
|
||||
I'm pleased to announce that Phaser 3.14 is now out. Hot on the heels of the massive 3.13 release, 3.14 brings some sought-after new features to the party, including support for the new Tiled Map Editor 1.2 file formats, as well as the long-requested feature allowing use of multiple tilesets per single tilemap layer.
|
||||
One thing I've been seeing asked for a lot on the Phaser Discord is the ability to 'save' a Render Texture to an image. So, I added the new methods `RenderTexture.snapshot` and `snapshotArea`. This allows you to grab whatever is on the Render Texture at that point in time and turn it into an Image. You could then save this image to the Texture Manager, if needed, or just save it out to the filesystem, or transmit it to as web service. Great for things like avatar creators or art packages.
|
||||
|
||||
There are also new features to make Matter JS debugging easier and body creation when using lists of vertices is now much cleaner too. It's never just features though. There are lots of important fixes and updates in 3.14, including a fix causing gl canvas resizing to fail, better handling of the game shutdown process and fixes for an issue with Graphics.generateTexture.
|
||||
You'll find loads more great new features, updates and fixes. So, as usual, please do spend some time digging through the [Change Log](#changelog). I assure you, it's worth while :)
|
||||
|
||||
If you're building an active project on 3.13 then please upgrade to 3.14 and, as usual, report any issues you find on GitHub so we can look at them immediately. Also, in the 3.14 release we have completed over 1000 new areas of documentation. At the time of writing there are now just 1900 items in the API left to document, which may sound like a lot, but is a fraction of the tens of thousands already done! With our current progress we should have 100% documentation coverage within the next couple of months.
|
||||
|
||||
In case you missed the notice, Phaser 3.13 introduced the Facebook Instant Games Plugin. The plugin provides a seamless bridge between Phaser and version 6.2 of the Facebook Instant Games SDK. Every single SDK function is available via the plugin and we will keep track of the official SDK to make sure they stay in sync. My thanks to Facebook for helping make this possible.
|
||||
|
||||
Also new in 3.13 were the Shape Game Objects, which allows for quick addition of geometry onto the display list. Easily add rectangles, triangles, curves, stars and more into your game and treat them just like any other Game Object. Perfect for place-holder art, abstract style games or just really fast iterations game-jam style.
|
||||
|
||||
3.14 continues to represent the tireless effort on my part to get it fully production ready. I'm seeing lots more games being released with Phaser 3 and stacks of tutorials and plugins are starting to surface. 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.
|
||||
A massive thank-you to everyone who supports Phaser on Patreon and PayPal. Your continued backing has allowed me to work on Phaser all year, 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.
|
||||
|
||||
|
@ -62,19 +52,32 @@ Rich - [@photonstorm](https://twitter.com/photonstorm)
|
|||
|
||||
![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.
|
||||
Because Phaser is an open source project, we cannot charge for it in the same way as traditional retail software. What's more, we don't ever want to. After all, it's built on, and was born from, open web standards. It's part of our manifesto that the core framework will always be free, even if you use it commercially, as many of you do.
|
||||
|
||||
If you have found Phaser useful in your development life or have made income as a result of it please support our work via:
|
||||
**You may not realize it, but because of this, we rely 100% on community backing to fund development.**
|
||||
|
||||
* 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).
|
||||
Those funds allow Phaser to improve, and when it improves, everyone involved benefits. Your support helps secure a constant cycle of updates, fixes, new features and planning for the future.
|
||||
|
||||
It all helps and genuinely contributes towards future development.
|
||||
There are other benefits to [backing Phaser](https://www.patreon.com/join/photonstorm), too:
|
||||
|
||||
Extra special thanks to our top-tier sponsors: [Orange Games](http://orangegames.com) and [CrossInstall](https://crossinstall.com).
|
||||
![Backers Perks](https://phaser.io/images/github/patreon-perk-chart.png)
|
||||
|
||||
![Sponsors](https://phaser.io/images/github/patreon-sponsors-2018-1.png "Top Patreon Sponsors")
|
||||
We use [Patreon](https://www.patreon.com/photonstorm) to manage the backing and you can [support Phaser](https://www.patreon.com/join/photonstorm?) from $1 per month. The amount you pledge is entirely up to you and can be changed as often as you like. Patreon renews monthly, just like Netflix. You can, of course, cancel at any point. Tears will be shed on this end, but that's not your concern.
|
||||
|
||||
Extra special thanks to the following companies who's support makes Phaser possible:
|
||||
|
||||
* [Cerebral Fix](https://cerebralfix.com)
|
||||
* [CrossInstall](https://crossinstall.com)
|
||||
* [Facebook](https://www.facebook.com)
|
||||
* [Game Distribution](https://gamedistribution.com)
|
||||
* [GameCommerce](https://www.gamecommerce.com)
|
||||
* [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/)
|
||||
|
||||
![Sponsors](https://phaser.io/images/github/sponsors-2019-08.png "Awesome Sponsors")
|
||||
|
||||
![Phaser Newsletter](https://phaser.io/images/github/div-newsletter.png "Phaser Newsletter")
|
||||
|
||||
|
@ -82,7 +85,7 @@ Extra special thanks to our top-tier sponsors: [Orange Games](http://orangegames
|
|||
|
||||
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.
|
||||
Over 140 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>
|
||||
|
@ -108,18 +111,18 @@ 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.15/dist/phaser.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/phaser@3.19.0/dist/phaser.js"></script>
|
||||
```
|
||||
|
||||
or the minified version:
|
||||
|
||||
```html
|
||||
<script src="//cdn.jsdelivr.net/npm/phaser@3.15/dist/phaser.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/phaser@3.19.0/dist/phaser.min.js"></script>
|
||||
```
|
||||
|
||||
### API Documentation
|
||||
|
||||
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.
|
||||
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 namespaces, classes and Game Objects lists.
|
||||
|
||||
Or, if you wish to run the docs locally you can checkout the [phaser3-docs](https://github.com/photonstorm/phaser3-docs) repository and then read the documentation by pointing your browser to the `docs/` folder.
|
||||
|
||||
|
@ -127,11 +130,20 @@ The documentation for Phaser 3 is an on-going project. Please help us by searchi
|
|||
|
||||
### TypeScript Definitions
|
||||
|
||||
[TypeScript Definitions](https://github.com/photonstorm/phaser3-docs/tree/master/typescript) are now available.
|
||||
The [TypeScript definitions](https://github.com/photonstorm/phaser/tree/master/types) can be found inside the `types` folder. They are also referenced in the types entry in `package.json`.
|
||||
|
||||
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.
|
||||
Depending on your project, you may need to add the following to your `tsconfig.json` file:
|
||||
|
||||
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.
|
||||
```json
|
||||
"typeRoots": [
|
||||
"./node_modules/phaser/types"
|
||||
],
|
||||
"types": [
|
||||
"Phaser"
|
||||
]
|
||||
```
|
||||
|
||||
The defs are automatically generated from the JSDoc comments found in the Phaser source code. If you wish to help refine them then you must edit the Phaser JSDoc blocks directly, not the defs file. You can find more details about the parser we built in the `scripts/tsgen` folder.
|
||||
|
||||
### Webpack
|
||||
|
||||
|
@ -186,20 +198,20 @@ We've 3 tutorials related to Facebook Instant Games and Phaser:
|
|||
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.15/dist/phaser-facebook-instant-games.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/phaser@3.19.0/dist/phaser-facebook-instant-games.js"></script>
|
||||
```
|
||||
|
||||
or the minified version:
|
||||
|
||||
```html
|
||||
<script src="//cdn.jsdelivr.net/npm/phaser@3.15/dist/phaser-facebook-instant-games.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/phaser@3.19.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. 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.
|
||||
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.
|
||||
|
||||
### Create Your First Phaser 3 Example
|
||||
|
||||
|
@ -209,7 +221,7 @@ Create an `index.html` page locally and paste the following code into it:
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="https://labs.phaser.io/build/phaser-arcade-physics.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/phaser@3.19.0/dist/phaser-arcade-physics.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
@ -320,47 +332,160 @@ You can then run `webpack` to create a development build in the `build` folder w
|
|||
|
||||
# Change Log
|
||||
|
||||
## Version 3.15.1 - Batou - 16th October 2018
|
||||
## Version 3.19.0 - Naofumi - 8th August 2019
|
||||
|
||||
Note: We are releasing this version ahead of schedule in order to make some very important iOS performance and input related fixes available. It does not contain the new Scale Manager or Spine support, both of which have been moved to 3.16 as they require a few more weeks of development.
|
||||
### Tween Updates
|
||||
|
||||
* All Tween classes and functions have 100% complete JSDocs :)
|
||||
* `StaggerBuilder` is a new function that allows you to define a staggered tween property. For example, as part of a tween config: `delay: this.tweens.stagger(500)` would stagger the delay by 500ms for every target of the tween. You can also provide a range: `delay: this.tweens.stagger([ 500, 1000 ])` which is spread across all targets. Finally, you can provide a Stagger Config object as the second argument. This allows you to define a stagger grid, direction, starting value and more. Please see the API Docs and new Examples for further details.
|
||||
* `Tween` now extends the Event Emitter class, allowing it to emit its own events and be listened to.
|
||||
* `Tween.ACTIVE_EVENT` is a new event that is dispatched when a tween becomes active. Listen to it with `tween.on('active')`.
|
||||
* `Tween.COMPLETE_EVENT` is a new event that is dispatched when a tween completes or is stopped. Listen to it with `tween.on('complete')`.
|
||||
* `Tween.LOOP_EVENT` is a new event that is dispatched when a tween loops, after any loop delay expires. Listen to it with `tween.on('loop')`.
|
||||
* `Tween.REPEAT_EVENT` is a new event that is dispatched when a tween property repeats, after any repeat delay expires. Listen to it with `tween.on('repeat')`.
|
||||
* `Tween.START_EVENT` is a new event that is dispatched when a tween starts. Listen to it with `tween.on('start')`.
|
||||
* `Tween.UPDATE_EVENT` is a new event that is dispatched when a tween property updates. Listen to it with `tween.on('update')`.
|
||||
* `Tween.YOYO_EVENT` is a new event that is dispatched when a tween property yoyos, after any hold delay expires. Listen to it with `tween.on('yoyo')`.
|
||||
* `Tween.onActive` is a new callback that is invoked the moment the Tween Manager brings the tween to life, even though it may not have yet started actively tweening anything due to delay settings.
|
||||
* `Tween.onStart` is now only invoked when the Tween actually starts tweening a value. Previously, it was invoked as soon as the Tween Manager activated the Tween. This has been recoded and this action is now handled by the `onActive` callback. Fix #3330 (thanks @wtravO)
|
||||
* `Tween.seek` has been rewritten so you can now seek to any point in the Tween, regardless of repeats, loops, delays and hold settings. Seeking will not invoke any callbacks or events during the seek. Fix #4409 (thanks @cristib84)
|
||||
* You can now set `from` and `to` values for a property, i.e. `alpha: { from: 0, to: 1 }` which would set the alpha of the target to 0 and then tween it to 1 _after_ any delays have expired. Fix #4493 (thanks @BigZaphod)
|
||||
* You can now set `start` and `to` values for a property, i.e. `alpha: { start: 0, to: 1 }` which would set the alpha of the target to 0 immediately, as soon as the Tween becomes active, and then tween it to 1 over the duration of the tween.
|
||||
* You can now set `start`, `from` and `to` values for a property, i.e. `alpha: { start: 0, from: 0.5, to: 1 }` which would set the alpha of the target to 0 immediately, as soon as the Tween becomes active, then after any delays it would set the alpha to 0.5 and then tween it to 1 over the duration of the Tween.
|
||||
* `Tween.hasStarted` is a new property that holds a flag signifying if the Tween has started or not. A Tween that has started is one that is actively tweening a property and not just in a delayed state.
|
||||
* `Tween.startDelay` is a new property that is set during the Tween init to hold the shortest possible time before the Tween will start tweening a value. It is decreased each update until it hits zero, after which the `onStart` callback is invoked.
|
||||
* `Tween.init` and `Tween.play` have been rewritten so they are not run multiple times when a Tween is paused before playback, or is part of a Timeline. This didn't cause any problems previously, but it was a redundant duplication of calls.
|
||||
* `Tween.onLoop` will now be invoked _after_ the `loopDelay` has expired, if any was set.
|
||||
* `Tween.onRepeat` will now be invoked _after_ the `repeatDelay` has expired, if any was set.
|
||||
* `easeParams` would be ignored for tweens that _didn't_ use a string for the ease function name. Fix #3826 (thanks @SBCGames)
|
||||
* You can now specify `easeParams` for any custom easing function you wish to use. Fix #3826 (thanks @SBCGames)
|
||||
* All changes to `Tween.state` are now set _before_ any events or callbacks, allowing you to modify the state of the Tween in those handlers (thanks @Cudabear)
|
||||
* `Tween.dispatchTweenEvent` is a new internal method that handles dispatching the new Tween Events and callbacks. This consolidates a lot of duplicate code into a single method.
|
||||
* `Tween.dispatchTweenDataEvent` is a new internal method that handles dispatching the new TweenData Events and callbacks. This consolidates a lot of duplicate code into a single method.
|
||||
* `Tween.isSeeking` is a new internal boolean flag that is used to keep track of the seek progress of a Tween.
|
||||
* `Timeline.onLoop` will now be invoked _after_ the `loopDelay` has expired, if any was set.
|
||||
* `Timeline.onComplete` will now be invoked _after_ the `completeDelay` has expired, if any was set.
|
||||
* All changes to `Timeline.state` are now set _before_ any events or callbacks, allowing you to modify the state of the Timeline in those handlers.
|
||||
* The `TIMELINE_LOOP_EVENT` has had the `loopCounter` argument removed from it. It didn't actually send the number of times the Timeline had looped (it actually sent the total remaining).
|
||||
* When a TweenData completes it will now set the `current` property to be exactly either `start` or `end` depending on playback direction.
|
||||
* When a TweenData completes it will set the exact `start` or `end` value into the target property.
|
||||
* `TweenData` has a new function signature, with the new `index` and `getActive`arguments added to it. `TweenBuilder` has been updated to set these, but if you create any TweenData objects directly, use the new signature.
|
||||
* `TweenData.getActiveValue` is a new property that, if not null, returns a value to immediately sets the property value to on activation.
|
||||
* `GetEaseFunction`, and by extension anything that uses it, such as setting the ease for a Tween, will now accept a variety of input strings as valid. You can now use lower-case, such as `back`, and omit the 'ease' part of the direction, such as `back.in` or `back.inout`.
|
||||
* The signature of `getStart` and `getEnd` custom property functions has changed to `(target, key, value, targetIndex, totalTargets, tween)`, previously it was just `(target, key, value)`. Custom functions don't need to change as the new arguments are in addition to those sent previously.
|
||||
* The signature of the LoadValue generator functions (such as `delay` and `repeat`) has changed to `(target, key, value, targetIndex, totalTargets, tween)` to match those of the custom property functions. If you used a custom generator function for your Tween configs you'll need to modify the signature to the new one.
|
||||
* Tweens created via `TweenManager.create` wouldn't start when `Tween.play` was called without first making them active manually. They now start automatically. Fix #4632 (thanks @mikewesthad)
|
||||
|
||||
### Spine Updates
|
||||
|
||||
The Spine Plugin is now 100% complete. It has been updated to use the Spine 3.7 Runtimes. Improvements have been made across the entire plugin, including proper batched rendering support in WebGL, cleaner skin and slot functions and lots and lots of updates. It's fully documented and there are lots of examples to be found. The following legacy bugs have also been fixed:
|
||||
|
||||
* Adding Spine to physics causes position to become NaN. Fix #4501 (thanks @hizzd)
|
||||
* Destroying a Phaser Game instance and then re-creating it would cause an error trying to re-create Spine Game Objects ("Cannot read property get of null"). Fix #4532 (thanks @Alex-Badea)
|
||||
* Rendering a Spine object when a Camera has `renderToTexture` enabled on it would cause the object to be vertically flipped. It now renders correctly in both cases. Fix #4647 (thanks @probt)
|
||||
|
||||
### New Features
|
||||
|
||||
* You can now set the `maxLights` value in the Game Config, which controls the total number of lights the Light2D shader can render in a single pass. The default is 10. Be careful about pushing this too far. More lights = less performance. Close #4081 (thanks @FrancescoNegri)
|
||||
* `Rectangle.SameDimensions` determines if the two objects (either Rectangles or Rectangle-like) have the same width and height values under strict equality.
|
||||
* An ArcadePhysics Group can now pass `{ enable: false }`` in its config to disable all the member bodies (thanks @samme)
|
||||
* `Body.setEnable` is a new chainable method that allows you to toggle the enable state of an Arcade Physics Body (thanks @samme)
|
||||
* `KeyboardPlugin.resetKeys` is a new method that will reset the state of any Key object created by a Scene's Keyboard Plugin.
|
||||
* `Pointer.wasCanceled` is a new boolean property that allows you to tell if a Pointer was cleared due to a `touchcancel` event. This flag is reset during the next `touchstart` event for the Pointer.
|
||||
* `Pointer.touchcancel` is a new internal method specifically for handling touch cancel events. It has the same result as `touchend` without setting any of the up properties, to avoid triggering up event handlers. It will also set the `wasCanceled` property to `true`.
|
||||
* `Shader.setRenderToTexture` is a new method that will redirect the Shader to render to its own framebuffer / WebGLTexture instead of to the display list. This allows you to use the output of the shader as an input for another shader, by mapping a sampler2D uniform to it. It also allows you to save the Shader to the Texture Manager, allowing you to use it as a texture for any other texture based Game Object such as a Sprite.
|
||||
* `Shader.setSampler2DBuffer` is a new method that allows you to pass a WebGLTexture directly into a Shader as a sampler2D uniform, such as when linking shaders together as buffers for each other.
|
||||
* `Shader.renderToTexture` is a new property flag that is set if you set the Shader to render to a texture.
|
||||
* `Shader.framebuffer` is a new property that contains a WebGLFramebuffer reference which is set if you set the Shader to render to a texture.
|
||||
* `Shader.glTexture` is a new property that contains a WebGLTexture reference which is set if you set the Shader to render to a texture.
|
||||
* `Shader.texture` is a new property that contains a Phaser Texture reference which is set if you set the Shader to save to the Texture Manager.
|
||||
* `TextureManager.addGLTexture` is a new method that allows you to add a WebGLTexture directly into the Texture Manager, saved under the given key.
|
||||
* `TextureSource.isGLTexture` is a new boolean property that reflects if the data backing the underlying Texture Source is a WebGLTexture or not.
|
||||
* `TextureTintPipeline.batchSprite` will now flip the UV if the TextureSource comes from a GLTexture.
|
||||
* `Math.ToXY` is a new mini function that will take a given index and return a Vector2 containing the x and y coordinates of that index within a grid.
|
||||
* `RenderTexture.glTexture` is a new property that holds a reference to the WebGL Texture being used by the Render Texture. Useful for passing to a shader as a sampler2D.
|
||||
* `GroupCreateConfig.quantity` - when creating a Group using a config object you can now use the optional property `quantity` to set the number of objects to be created. Use this for quickly creating groups of single frame objects that don't need the advanced capabilities of `frameQuantity` and `repeat`.
|
||||
* `Pointer.locked` is a new read-only property that indicates if the pointer has been Pointer Locked, or not, via the Pointer Lock API.
|
||||
* `WebGLRenderer.snapshotFramebuffer`, and the corresponding utility function `WebGLSnapshot`, allows you to take a snapshot of a given WebGL framebuffer, such as the one used by a Render Texture or Shader, and either get a single pixel from it as a Color value, or get an area of it as an Image object, which can then optionally be saved to the Texture Manager for use by Game Object textures.
|
||||
* `CanvasRenderer.snapshotCanvas` allows you to take a snapshot of a given Canvas object, such as the one used by a Render Texture, and either get a single pixel from it as a Color value, or get an area of it as an Image object, which can then optionally be saved to the Texture Manager for use by Game Object textures.
|
||||
* `RenderTexture.snapshot` is a new method that will take a snapshot of the whole current state of the Render Texture and return it as an Image object, which could then be saved to the Texture Manager if needed.
|
||||
* `RenderTexture.snapshotArea` is a new method that will take a snapshot of an area of a Render Texture and return it as an Image object, which could then be saved to the Texture Manager if needed.
|
||||
* `RenderTexture.snapshotPixel` is a new method that will take extract a single pixel color value from a Render Texture and return it as a Color object.
|
||||
* The `SnapshotState` object has three new properties: `isFramebuffer` boolean and `bufferWidth` and `bufferHeight` integers.
|
||||
* `Game.CONTEXT_LOST_EVENT` is a new event that is dispatched by the Game instance when the WebGL Renderer webgl context is lost. Use this instead of the old 'lostContextCallbacks' for cleaner context handling.
|
||||
* `Game.CONTEXT_RESTORED_EVENT` is a new event that is dispatched by the Game instance when the WebGL Renderer webgl context is restored. Use this instead of the old 'restoredContextCallbacks' for cleaner context handling.
|
||||
* `WebGLRenderer.currentType` contains the type of the Game Object currently being rendered.
|
||||
* `WebGLRenderer.newType` is a boolean that indicates if the current Game Object has a new type, i.e. different to the previous one in the display list.
|
||||
* `WebGLRenderer.nextTypeMatch` is a boolean that indicates if the _next_ Game Object in the display list has the same type as the one being currently rendered. This allows you to build batching into separated Game Objects.
|
||||
* `PluginManager.removeGameObject` is a new method that allows you to de-register custom Game Object types from the global Game Object Factory and/or Creator. Useful for when custom plugins are destroyed and need to clean-up after themselves.
|
||||
* `GEOM_CONST` is a new constants object that contains the different types of Geometry Objects, such as `RECTANGLE` and `CIRCLE`.
|
||||
* `Circle.type` is a new property containing the shapes geometry type, which can be used for quick type comparisons.
|
||||
* `Ellipse.type` is a new property containing the shapes geometry type, which can be used for quick type comparisons.
|
||||
* `Line.type` is a new property containing the shapes geometry type, which can be used for quick type comparisons.
|
||||
* `Point.type` is a new property containing the shapes geometry type, which can be used for quick type comparisons.
|
||||
* `Polygon.type` is a new property containing the shapes geometry type, which can be used for quick type comparisons.
|
||||
* `Rectangle.type` is a new property containing the shapes geometry type, which can be used for quick type comparisons.
|
||||
* `Triangle.type` is a new property containing the shapes geometry type, which can be used for quick type comparisons.
|
||||
* `InputPlugin.enableDebug` is a new method that will create a debug shape for the given Game Objects hit area. This allows you to quickly check the size and placement of an input hit area. You can customzie the shape outline color. The debug shape will automatically track the Game Object to which it is bound.
|
||||
* `InputPlugion.removeDebug` will remove a Debug Input Shape from the given Game Object and destroy it.
|
||||
* `Pointer.updateWorldPoint` is a new method that takes a Camera and then updates the Pointers `worldX` and `worldY` values based on the cameras transform (thanks @Nick-lab)
|
||||
* `ScaleManager._resetZoom` is a new internal flag that is set when the game zoom factor changes.
|
||||
* `Texture.remove` is a new method that allows you to remove a Frame from a Texture based on its name. Fix #4460 (thanks @BigZaphod)
|
||||
|
||||
### Updates
|
||||
|
||||
* `WebGLRenderer.deleteTexture` will check to see if the texture it is being asked to delete is the currently bound texture or not. If it is, it'll set the blank texture to be bound after deletion. This should stop `RENDER WARNING: there is no texture bound to the unit 0` errors if you destroy a Game Object, such as Text or TileSprite, from an async or timed process (thanks jamespierce)
|
||||
* The `RequestAnimationFrame.step` and `stepTimeout` functions have been updated so that the new Frame is requested from raf before the main game step is called. This allows you to now stop the raf callback from within the game update or render loop. Fix #3952 (thanks @tolimeh)
|
||||
* If you pass zero as the width or height when creating a TileSprite it will now use the dimensions of the texture frame as the size of the TileSprite. Fix #4073 (thanks @jcyuan)
|
||||
* `TileSprite.setFrame` has had both the `updateSize` and `updateOrigin` arguments removed as they didn't do anything for TileSprites and were misleading.
|
||||
* `CameraManager.remove` has a new argument `runDestroy` which, if set, will automatically call `Camera.destroy` on the Cameras removed from the Camera Manager. You should nearly always allow this to happen (thanks jamespierce)
|
||||
* Device.OS has been restructured to allow fake UAs from Chrome dev tools to register iOS devices.
|
||||
* Texture batching during the batch flush has been implemented in the TextureTintPipeline which resolves the issues of very low frame rates, especially on iOS devices, when using non-batched textures such as those used by Text or TileSprites. Fix #4110 #4086 (thanks @ivanpopelyshev @sachinhosmani @maximtsai @alexeymolchan)
|
||||
* The WebGLRenderer method `canvasToTexture` has a new optional argument `noRepeat` which will stop it from using `gl.REPEAT` entirely. This is now used by the Text object to avoid it potentially switching between a REPEAT and CLAMP texture, causing texture black-outs (thanks @ivanpopelyshev)
|
||||
* `KeyboardPlugin.resetKeys` is now called automatically as part of the Keyboard Plugin `shutdown` method. This means, when the plugin shuts down, such as when stopping a Scene, it will reset the state of any key held in the plugin. It will also clear the queue of any pending events.
|
||||
* The `Touch Manager` has been rewritten to use declared functions for all touch event handlers, rather than bound functions. This means they will now clear properly when the TouchManager is shut down.
|
||||
* There is a new Input constant `TOUCH_CANCEL` which represents canceled touch events.
|
||||
* When calling `setHitArea` and not providing a shape (i.e. a texture based hit area), it will now set `customHitArea` to `false` by default (thanks @rexrainbow)
|
||||
* The Shader will no longer set uniforms if the values are `null`, saving on GL ops.
|
||||
* The Animation Manager will now emit a console warning if you try and play an animation on a Sprite that doesn't exist.
|
||||
* The Animation component will no longer start an animation on a Sprite if the animation doesn't exist. Previously it would throw an error saying "Unable to read the property getFirstTick of null".
|
||||
* `InputManager.onPointerLockChange` is a new method that handles pointer lock change events and dispatches the lock event.
|
||||
* `CanvasTexture` has been added to the `Textures` namespace so it can be created without needing to import it. The correct way to create a `CanvasTexture` is via the Texture Manager, but you can now do it directly if required. Fix #4651 (thanks @Jugacu)
|
||||
* The `SmoothedKeyControl` minimum zoom a Camera can go to is now 0.001. Previously it was 0.1. This is to make it match the minimum zoom a Base Camera can go to. Fix #4649 (thanks @giviz)
|
||||
* `WebGLRenderer.lostContextCallbacks` and the `onContextLost` method have been removed. Please use the new `CONTEXT_LOST` event instead.
|
||||
* `WebGLRenderer.restoredContextCallbacks` and the `onContextRestored` method have been removed. Please use the new `CONTEXT_RESTORED` event instead.
|
||||
* `TextureManager.getBase64` will now emit a console warning if you try to get a base64 from a non-image based texture, such as a WebGL Texture.
|
||||
* The `WebAudioSoundManager` will now remove the document touch handlers even if the Promise fails, preventing it from throwing a rejection handler error.
|
||||
* `GameObjectFactory.remove` is a new static function that will remove a custom Game Object factory type.
|
||||
* `GameObjectCreator.remove` is a new static function that will remove a custom Game Object creator type.
|
||||
* `CanvasTexture.getPixels` now defaults to 0x0 by width x height as the default area, allowing you to call the method with no arguments to get all the pixels for the canvas.
|
||||
* `CreateDOMContainer` will now use `div.style.cssText` to set the inline styles of the container, so it now works on IE11. Fix #4674 (thanks @DanLiamco)
|
||||
* `TransformMatrix.rotation` now returns the properly normalized rotation value.
|
||||
* `PhysicsEditorParser` has now been exposed under the `Phaser.Physics.Matter` namespace, so you can call methods on it directly.
|
||||
* Calling `CanvasTexture.update` will now automatically call `refresh` if running under WebGL. This happens for both `draw` and `drawFrame`, meaning you no longer need to remember to call `refresh` after drawing to a Canvas Texture in WebGL, keeping it consistent with the Canvas renderer.
|
||||
* `Frame.destroy` will now null the Frames reference to its parent texture, glTexture and clear the data and customData objects.
|
||||
* The Container renderer functions will now read the childs `alpha` property, instead of `_alpha`, allowing it to work with more variety of custom children.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a bug in the canvas rendering of both the Static and Dynamic Tilemap Layers where the camera matrix was being multiplied twice with the layer, causing the scale and placement to be off (thanks galerijanamar)
|
||||
* If you set `pixelArt` to true in your game config (or `antialias` to false) then TileSprites will now respect this when using the Canvas Renderer and disable smoothing on the internal fill canvas.
|
||||
* TileSprites that were set to be interactive before they had rendered once wouldn't receive a valid input hit area, causing input to fail. They now define their size immediately, allowing them to be made interactive without having rendered. Fix #4085 (thanks @DotTheGreat)
|
||||
* The Particle Emitter Manager has been given a NOOP method called `setBlendMode` to stop warnings from being thrown if you added an emitter to a Container in the Canvas renderer. Fix #4083 (thanks @maximtsai)
|
||||
* The `game.context` property would be incorrectly set to `null` after the WebGLRenderer instance was created (thanks @samme)
|
||||
* The Touch Manager, Input Manager and Pointer classes all now handle the `touchcancel` event, such as triggered on iOS when activating an out of browser UI gesture, or in Facebook Instant Games when displaying an overlay ad. This should prevent issues with touch input becoming locked on iOS specifically. Fix #3756 (thanks @sftsk @sachinhosmani @kooappsdevs)
|
||||
* The Scale Manager would throw the error 'TypeError: this.removeFullscreenTarget is not a function' when entering full-screen mode. It would still enter fullscreen, but the error would appear in the console. Fix #4605 (thanks @darklightcode)
|
||||
* `Tilemap.renderDebug` was calling out-dated Graphics API methods, which would cause the debug to fail (thanks @Fabadiculous)
|
||||
* The `Matter.Factory.constraint`, `joint` and `worldConstraint` methods wouldn't allow a zero length constraint to be created due to a falsey check of the length argument. You can now set length to be any value, including zero, or leave it undefined to have it automatically calculated (thanks @olilanz)
|
||||
* `Pointer.getDuration` would return a negative / static value on desktop, or NaN on mobile, because the base time wasn't being pulled in from the Input Manager properly. Fix #4612 (thanks @BobtheUltimateProgrammer)
|
||||
* `Pointer.downTime`, `Pointer.upTime` and `Pointer.moveTime` would be set to NaN on mobile browsers where Touch.timeStamp didn't exist. Fix #4612 (thanks @BobtheUltimateProgrammer)
|
||||
* `WebGLRenderer.setScissor` will default the `drawingBufferHeight` if no argument is provided, stopping NaN scissor heights.
|
||||
* If you called `Scene.destroy` within a Game Object `pointerdown` or `pointerup` handler, it would cause the error "Cannot read property 'game' of null" if the event wasn't cancelled in your handler. It now checks if the manager is still there before accessing its property. Fix #4436 (thanks @jcyuan)
|
||||
* The `Arc / Circle` Game Object wasn't rendering centered correctly in WebGL due to an issue in a previous size related commit, it would be half a radius off. Fix #4620 (thanks @CipSoft-Components @rexrainbow)
|
||||
* Destroying a Scene in HEADLESS mode would throw an error as it tried to access the gl renderer in the Camera class. Fix #4467 (thanks @AndreaBoeAbrahamsen @samme)
|
||||
* `Tilemap.createFromObjects` would ignore the `scene` argument passed in to the method. It's now used (thanks @samme)
|
||||
* Fixed a bug in the WebGL and Canvas Renderers where a Sprite with a `flipX` or `flipY` value set would render the offset frames slightly out of place, causing the animation to appear jittery. Also, the sprite would be out of place by its origin. Fix #4636 #3813 (thanks @jronn @B3L7)
|
||||
* Animations with custom pivots, like those created in Texture Packer with the pivot option enabled, would be mis-aligned if flipped. They now render in the correct position, regardless of scale or flip on either axis. Fix #4155 (thanks @Zax37)
|
||||
* Removing a frame from a 2 frame animation would cause an error when a Sprite using that animation next tried to render. Fix #4621 (thanks @orlicgms)
|
||||
* Calling `Animation.setRepeat()` wouldn't reset the `repeatCounter` properly, causing Sprite bound animation instances to fail to change their repeat rate. Fix #4553 (thanks @SavedByZero)
|
||||
* The `UpdateList.remove` method wouldn't flag the Game Object for removal properly if it was active. It now checks that the Game Object is in the current update list and hasn't already been inserted into the 'pending removal' list before flagging it. Fix #4544 (thanks @jcyuan)
|
||||
* `DynamicTilemapLayer.destroy` will now no longer run its destroy sequence again if it has already been run once. Fix #4634 (thanks @CipSoft-Components)
|
||||
* `StaticTilemapLayer.destroy` will now no longer run its destroy sequence again if it has already been run once.
|
||||
* `Shader.uniforms` now uses Extend instead of Clone to perform a deep object copy, instead of a shallow one, avoiding multiple instances of the same shader sharing uniforms. Fix #4641 (thanks @davidmball)
|
||||
* Calling `input.mouse.requestPointerLock()` will no longer throw an error about being unable to push to the Input Manager events queue.
|
||||
* The `POINTERLOCK_CHANGE` event is now dispatched by the Input Manager again.
|
||||
* The `Pointer.movementX` and `Pointer.movementY` properties are now taken directly from the DOM pointer event values, if the pointer is locked, and no longer incremental. Fix #4611 (thanks @davidmball)
|
||||
* The `Pointer.velocity` and `Pointer.midPoint` values are now updated every frame. Based on the `motionFactor` setting they are smoothed towards zero, for velocity, and the pointer position for the mid point. This now happens regardless if the Pointer moves or not, which is how it was originally intended to behave.
|
||||
* The `DESTROY` event hook wasn't removed from Group children when destroying the Group and `destroyChildren` was set to false. Now, the hook is removed regardless (thanks @rexrainbow)
|
||||
* The WebGL Lost and Restored Context callbacks were never removed, which could cause them to hold onto stale references. Fix #3610 (thanks @Twilrom)
|
||||
* `Origin.updateDisplayOrigin` no longer applies a Math.floor to the display origins, allowing you to have a 0.x origin for a Game Object that only has a width or height of 1. This fixes issues with things like 1x1 rectangles displaying incorrectly during rendering. Fix #4126 (thanks @rexrainbow)
|
||||
* `InputManager.resetCursor` will now check if the canvas element still exists before resetting the cursor on it. Fix #4662 (thanks @fromnowhereuser)
|
||||
* It was not possible to set the zoom value of the Scale Manager back to 1 again, having changed it to a different value. Fix #4633 (thanks @lgibson02 @BinaryMoon)
|
||||
|
||||
### Examples, Documentation and TypeScript
|
||||
|
||||
My thanks to the following for helping with the Phaser 3 Examples, Docs and TypeScript definitions, either by reporting errors, fixing them or helping author the docs:
|
||||
|
||||
@vacarsu @KennethGomez @samme @ldd @Jazcash @jcyuan @LearningCode2023 @PhaserEditor2D
|
||||
|
||||
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>
|
||||
|
||||
|
@ -382,14 +507,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 © 2018 Photon Storm Limited.
|
||||
The Phaser logo and characters are © 2019 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.15.1/phaser.js
|
||||
[get-minjs]: https://github.com/photonstorm/phaser/releases/download/v3.15.1/phaser.min.js
|
||||
[get-js]: https://github.com/photonstorm/phaser/releases/download/v3.19.0/phaser.js
|
||||
[get-minjs]: https://github.com/photonstorm/phaser/releases/download/v3.19.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
|
||||
|
|
|
@ -6,14 +6,14 @@ const exec = require('child_process').exec;
|
|||
module.exports = {
|
||||
mode: 'development',
|
||||
|
||||
context: `${__dirname}/src/`,
|
||||
context: `${__dirname}/../src/`,
|
||||
|
||||
entry: {
|
||||
phaser: './phaser.js'
|
||||
},
|
||||
|
||||
output: {
|
||||
path: `${__dirname}/build/`,
|
||||
path: `${__dirname}/../build/`,
|
||||
filename: '[name].js',
|
||||
library: 'Phaser',
|
||||
libraryTarget: 'umd',
|
||||
|
@ -31,7 +31,8 @@ module.exports = {
|
|||
"typeof WEBGL_RENDERER": JSON.stringify(true),
|
||||
"typeof EXPERIMENTAL": JSON.stringify(true),
|
||||
"typeof PLUGIN_CAMERA3D": JSON.stringify(false),
|
||||
"typeof PLUGIN_FBINSTANT": JSON.stringify(false)
|
||||
"typeof PLUGIN_FBINSTANT": JSON.stringify(false),
|
||||
"typeof FEATURE_SOUND": JSON.stringify(true)
|
||||
}),
|
||||
{
|
||||
apply: (compiler) => {
|
|
@ -4,10 +4,13 @@ const webpack = require('webpack');
|
|||
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
|
||||
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||
|
||||
const basePath = __dirname;
|
||||
const targetFolder = 'dist';
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
|
||||
context: `${__dirname}/src/`,
|
||||
context: `${__dirname}/../src/`,
|
||||
|
||||
entry: {
|
||||
phaser: './phaser.js',
|
||||
|
@ -17,7 +20,7 @@ module.exports = {
|
|||
},
|
||||
|
||||
output: {
|
||||
path: `${__dirname}/dist/`,
|
||||
path: `${__dirname}/../dist/`,
|
||||
filename: '[name].js',
|
||||
library: 'Phaser',
|
||||
libraryTarget: 'umd',
|
||||
|
@ -50,9 +53,12 @@ module.exports = {
|
|||
"typeof WEBGL_RENDERER": JSON.stringify(true),
|
||||
"typeof EXPERIMENTAL": JSON.stringify(false),
|
||||
"typeof PLUGIN_CAMERA3D": JSON.stringify(false),
|
||||
"typeof PLUGIN_FBINSTANT": JSON.stringify(false)
|
||||
"typeof PLUGIN_FBINSTANT": JSON.stringify(false),
|
||||
"typeof FEATURE_SOUND": JSON.stringify(true)
|
||||
}),
|
||||
|
||||
new CleanWebpackPlugin([ 'dist' ])
|
||||
new CleanWebpackPlugin([targetFolder], {
|
||||
root: basePath + '/../'
|
||||
})
|
||||
]
|
||||
};
|
|
@ -6,14 +6,14 @@ const exec = require('child_process').exec;
|
|||
module.exports = {
|
||||
mode: 'development',
|
||||
|
||||
context: `${__dirname}/src/`,
|
||||
context: `${__dirname}/../src/`,
|
||||
|
||||
entry: {
|
||||
phaser: './phaser.js'
|
||||
},
|
||||
|
||||
output: {
|
||||
path: `${__dirname}/build/`,
|
||||
path: `${__dirname}/../build/`,
|
||||
filename: 'phaser-facebook-instant-games.js',
|
||||
library: 'Phaser',
|
||||
libraryTarget: 'umd',
|
||||
|
@ -31,7 +31,8 @@ module.exports = {
|
|||
"typeof WEBGL_RENDERER": JSON.stringify(true),
|
||||
"typeof EXPERIMENTAL": JSON.stringify(false),
|
||||
"typeof PLUGIN_CAMERA3D": JSON.stringify(false),
|
||||
"typeof PLUGIN_FBINSTANT": JSON.stringify(true)
|
||||
"typeof PLUGIN_FBINSTANT": JSON.stringify(true),
|
||||
"typeof FEATURE_SOUND": JSON.stringify(true)
|
||||
}),
|
||||
{
|
||||
apply: (compiler) => {
|
|
@ -6,7 +6,7 @@ const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
|
|||
module.exports = {
|
||||
mode: 'production',
|
||||
|
||||
context: `${__dirname}/src/`,
|
||||
context: `${__dirname}/../src/`,
|
||||
|
||||
entry: {
|
||||
'phaser-facebook-instant-games': './phaser.js',
|
||||
|
@ -14,7 +14,7 @@ module.exports = {
|
|||
},
|
||||
|
||||
output: {
|
||||
path: `${__dirname}/dist/`,
|
||||
path: `${__dirname}/../dist/`,
|
||||
filename: '[name].js',
|
||||
library: 'Phaser',
|
||||
libraryTarget: 'umd',
|
||||
|
@ -47,7 +47,8 @@ module.exports = {
|
|||
"typeof WEBGL_RENDERER": JSON.stringify(true),
|
||||
"typeof EXPERIMENTAL": JSON.stringify(false),
|
||||
"typeof PLUGIN_CAMERA3D": JSON.stringify(false),
|
||||
"typeof PLUGIN_FBINSTANT": JSON.stringify(true)
|
||||
"typeof PLUGIN_FBINSTANT": JSON.stringify(true),
|
||||
"typeof FEATURE_SOUND": JSON.stringify(true)
|
||||
})
|
||||
]
|
||||
};
|
284571
dist/phaser-arcade-physics.js
vendored
284571
dist/phaser-arcade-physics.js
vendored
File diff suppressed because it is too large
Load diff
2
dist/phaser-arcade-physics.min.js
vendored
2
dist/phaser-arcade-physics.min.js
vendored
File diff suppressed because one or more lines are too long
320482
dist/phaser-facebook-instant-games.js
vendored
320482
dist/phaser-facebook-instant-games.js
vendored
File diff suppressed because it is too large
Load diff
2
dist/phaser-facebook-instant-games.min.js
vendored
2
dist/phaser-facebook-instant-games.min.js
vendored
File diff suppressed because one or more lines are too long
317654
dist/phaser.js
vendored
317654
dist/phaser.js
vendored
File diff suppressed because it is too large
Load diff
2
dist/phaser.min.js
vendored
2
dist/phaser.min.js
vendored
File diff suppressed because one or more lines are too long
394
package-lock.json
generated
394
package-lock.json
generated
File diff suppressed because it is too large
Load diff
41
package.json
41
package.json
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"name": "phaser",
|
||||
"version": "3.16.0",
|
||||
"release": "Ishikawa",
|
||||
"version": "3.20.0-beta1",
|
||||
"release": "Fitoria",
|
||||
"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)",
|
||||
"logo": "https://raw.github.com/photonstorm/phaser/master/phaser-logo-small.png",
|
||||
"homepage": "http://phaser.io",
|
||||
"bugs": "https://github.com/photonstorm/phaser/issues",
|
||||
"license": "MIT",
|
||||
"licenseUrl": "http://www.opensource.org/licenses/mit-license.php",
|
||||
"main": "./src/phaser.js",
|
||||
"types": "./types/phaser.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://photonstorm@github.com/photonstorm/phaser.git"
|
||||
|
@ -17,26 +17,36 @@
|
|||
"scripts": {
|
||||
"beta": "npm publish --tag beta",
|
||||
"help": "node scripts/help.js",
|
||||
"build": "webpack",
|
||||
"watch": "webpack --watch",
|
||||
"buildfb": "webpack --config webpack.fb.config.js",
|
||||
"watchfb": "webpack --config webpack.fb.config.js --watch",
|
||||
"dist": "webpack --config webpack.dist.config.js",
|
||||
"distfb": "webpack --config webpack.fb.dist.config.js",
|
||||
"build": "webpack --config config/webpack.config.js",
|
||||
"watch": "webpack --watch --config config/webpack.config.js",
|
||||
"buildfb": "webpack --config config/webpack.fb.config.js",
|
||||
"watchfb": "webpack --config config/webpack.fb.config.js --watch",
|
||||
"dist": "webpack --config config/webpack.dist.config.js",
|
||||
"distfb": "webpack --config config/webpack.fb.dist.config.js",
|
||||
"distfull": "npm run dist && npm run distfb",
|
||||
"plugin.cam3d": "webpack --config plugins/camera3d/webpack.config.js",
|
||||
"plugin.spine": "webpack --config plugins/spine/webpack.config.js",
|
||||
"plugin.spine.dist": "webpack --config plugins/spine/webpack.auto.dist.config.js",
|
||||
"plugin.spine.watch": "webpack --config plugins/spine/webpack.auto.config.js --watch --display-modules",
|
||||
"plugin.spine.dev": "webpack --config plugins/spine/webpack.auto.config.js",
|
||||
"plugin.spine.canvas.dist": "webpack --config plugins/spine/webpack.canvas.dist.config.js",
|
||||
"plugin.spine.canvas.watch": "webpack --config plugins/spine/webpack.canvas.config.js --watch --display-modules",
|
||||
"plugin.spine.canvas.dev": "webpack --config plugins/spine/webpack.canvas.config.js",
|
||||
"plugin.spine.webgl.dist": "webpack --config plugins/spine/webpack.webgl.dist.config.js",
|
||||
"plugin.spine.webgl.watch": "webpack --config plugins/spine/webpack.webgl.config.js --watch",
|
||||
"plugin.spine.webgl.watch": "webpack --config plugins/spine/webpack.webgl.config.js --watch --display-modules",
|
||||
"plugin.spine.webgl.dev": "webpack --config plugins/spine/webpack.webgl.config.js",
|
||||
"plugin.spine.full": "npm run plugin.spine.dev && npm run plugin.spine.canvas.dev && npm run plugin.spine.webgl.dev",
|
||||
"plugin.spine.full.dist": "npm run plugin.spine.dist && npm run plugin.spine.canvas.dist && npm run plugin.spine.webgl.dist",
|
||||
"lint": "eslint --config .eslintrc.json \"src/**/*.js\"",
|
||||
"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"
|
||||
"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",
|
||||
"ts": "npm run tsgen && npm run test-ts",
|
||||
"tsdev": "npm run build-tsgen && npm run tsgen && npm run test-ts"
|
||||
},
|
||||
"keywords": [
|
||||
"2d",
|
||||
|
@ -54,7 +64,7 @@
|
|||
"clean-webpack-plugin": "^0.1.19",
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-plugin-es5": "^1.3.1",
|
||||
"fs-extra": "^6.0.0",
|
||||
"fs-extra": "^6.0.1",
|
||||
"node-sloc": "^0.1.11",
|
||||
"uglifyjs-webpack-plugin": "^1.3.0",
|
||||
"vivid-cli": "^1.1.2",
|
||||
|
@ -63,8 +73,13 @@
|
|||
"webpack-shell-plugin": "^0.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"dts-dom": "^3.2.0",
|
||||
"eventemitter3": "^3.1.0",
|
||||
"exports-loader": "^0.7.0",
|
||||
"imports-loader": "^0.8.0"
|
||||
"imports-loader": "^0.8.0",
|
||||
"jsdoc": "^3.6.1",
|
||||
"path": "^0.12.7",
|
||||
"remove-files-webpack-plugin": "^1.1.3",
|
||||
"typescript": "^3.4.5"
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 176 KiB |
|
@ -112,13 +112,12 @@ var Camera = new Class({
|
|||
*/
|
||||
this.position = new Vector3();
|
||||
|
||||
// The mapping from 3D size units to pixels.
|
||||
// In the default case 1 3D unit = 128 pixels. So a sprite that is
|
||||
// 256 x 128 px in size will be 2 x 1 units.
|
||||
// Change to whatever best fits your game assets.
|
||||
|
||||
/**
|
||||
* [description]
|
||||
* The mapping from 3D size units to pixels.
|
||||
* In the default case 1 3D unit = 128 pixels. So a sprite that is
|
||||
* 256 x 128 px in size will be 2 x 1 units.
|
||||
* Change to whatever best fits your game assets.
|
||||
*
|
||||
* @name Phaser.Cameras.Sprite3D#pixelScale
|
||||
* @type {number}
|
||||
|
|
|
@ -279,7 +279,7 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
* Contains all of the leaderboard data, as populated by the `getLeaderboard()` method.
|
||||
*
|
||||
* @name Phaser.FacebookInstantGamesPlugin#leaderboards
|
||||
* @type {Phaser.FacebookInstantGamesPlugin.Leaderboard[]}
|
||||
* @type {Phaser.FacebookInstantGamesLeaderboard[]}
|
||||
* @since 3.13.0
|
||||
*/
|
||||
this.leaderboards = {};
|
||||
|
@ -387,7 +387,7 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
{
|
||||
this.hasLoaded = true;
|
||||
|
||||
FBInstant.startGameAsync().then(this.gameStarted.bind(this));
|
||||
FBInstant.startGameAsync().then(this.gameStartedHandler.bind(this));
|
||||
}
|
||||
|
||||
}, this);
|
||||
|
@ -408,6 +408,27 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
* @since 3.13.0
|
||||
*/
|
||||
gameStarted: function ()
|
||||
{
|
||||
if (!this.hasLoaded)
|
||||
{
|
||||
this.hasLoaded = true;
|
||||
|
||||
FBInstant.startGameAsync().then(this.gameStartedHandler.bind(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.gameStartedHandler();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The internal gameStarted handler.
|
||||
*
|
||||
* @method Phaser.FacebookInstantGamesPlugin#gameStartedHandler
|
||||
* @private
|
||||
* @since 3.20.0
|
||||
*/
|
||||
gameStartedHandler: function ()
|
||||
{
|
||||
var APIs = FBInstant.getSupportedAPIs();
|
||||
|
||||
|
@ -667,7 +688,7 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
*
|
||||
* ```javascript
|
||||
* this.facebook.loadPlayerPhoto(this, 'player').once('photocomplete', function (key) {
|
||||
* this.add.image(x, y, 'player);
|
||||
* this.add.image(x, y, 'player');
|
||||
* }, this);
|
||||
* ```
|
||||
*
|
||||
|
@ -1308,6 +1329,16 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* A filter that may be applied to a Context Choose operation.
|
||||
*
|
||||
* 'NEW_CONTEXT_ONLY' - Prefer to only surface contexts the game has not been played in before.
|
||||
* 'INCLUDE_EXISTING_CHALLENGES' - Include the "Existing Challenges" section, which surfaces actively played-in contexts that the player is a part of.
|
||||
* 'NEW_PLAYERS_ONLY' - In sections containing individuals, prefer people who have not played the game.
|
||||
*
|
||||
* @typedef {string} ContextFilter
|
||||
*/
|
||||
|
||||
/**
|
||||
* Opens a context selection dialog for the player. If the player selects an available context,
|
||||
* the client will attempt to switch into that context, and emit the `choose` event if successful.
|
||||
|
@ -1316,13 +1347,16 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
* @method Phaser.FacebookInstantGamesPlugin#chooseContext
|
||||
* @since 3.13.0
|
||||
*
|
||||
* @param {string} contextID - The ID of the desired context.
|
||||
* @param {*} [options] - An object specifying conditions on the contexts that should be offered.
|
||||
* @param {ContextFilter[]} [options.filters] - The set of filters to apply to the context suggestions: 'NEW_CONTEXT_ONLY', 'INCLUDE_EXISTING_CHALLENGES' or 'NEW_PLAYERS_ONLY'.
|
||||
* @param {number} [options.maxSize] - The maximum number of participants that a suggested context should ideally have.
|
||||
* @param {number} [options.minSize] - The minimum number of participants that a suggested context should ideally have.
|
||||
*
|
||||
* @return {this} This Facebook Instant Games Plugin instance.
|
||||
*/
|
||||
chooseContext: function (options)
|
||||
{
|
||||
if (!this.checkAPI('contextChoseAsync'))
|
||||
if (!this.checkAPI('contextChooseAsync'))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
@ -1460,6 +1494,33 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetches a single Product from the game's product catalog.
|
||||
*
|
||||
* The product catalog must have been populated using `getCatalog` prior to calling this method.
|
||||
*
|
||||
* Use this to look-up product details based on a purchase list.
|
||||
*
|
||||
* @method Phaser.FacebookInstantGamesPlugin#getProduct
|
||||
* @since 3.17.0
|
||||
*
|
||||
* @param {string} productID - The Product ID of the item to get from the catalog.
|
||||
*
|
||||
* @return {?Product} The Product from the catalog, or `null` if it couldn't be found or the catalog isn't populated.
|
||||
*/
|
||||
getProduct: function (productID)
|
||||
{
|
||||
for (var i = 0; i < this.catalog.length; i++)
|
||||
{
|
||||
if (this.catalog[i].productID === productID)
|
||||
{
|
||||
return this.catalog[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Begins the purchase flow for a specific product.
|
||||
*
|
||||
|
@ -1569,14 +1630,14 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
* If they cannot, i.e. it's not in the list of supported APIs, or the request
|
||||
* was rejected, it will emit a `consumepurchasefail` event instead.
|
||||
*
|
||||
* @method Phaser.FacebookInstantGamesPlugin#consumePurchases
|
||||
* @since 3.13.0
|
||||
* @method Phaser.FacebookInstantGamesPlugin#consumePurchase
|
||||
* @since 3.17.0
|
||||
*
|
||||
* @param {string} purchaseToken - The purchase token of the purchase that should be consumed.
|
||||
*
|
||||
* @return {this} This Facebook Instant Games Plugin instance.
|
||||
*/
|
||||
consumePurchases: function (purchaseToken)
|
||||
consumePurchase: function (purchaseToken)
|
||||
{
|
||||
if (!this.paymentsReady)
|
||||
{
|
||||
|
@ -1624,7 +1685,7 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
* @param {string} cta - The call to action text.
|
||||
* @param {object} text - The text object.
|
||||
* @param {string} key - The key of the texture to use as the share image.
|
||||
* @param {(string|integer)} [frame] - The frame of the texture to use as the share image. Set to `null` if you don't require a frame, but do need to set session data.
|
||||
* @param {?(string|integer)} frame - The frame of the texture to use as the share image. Set to `null` if you don't require a frame, but do need to set session data.
|
||||
* @param {string} template - The update template key.
|
||||
* @param {object} updateData - The update data object payload.
|
||||
*
|
||||
|
@ -1662,7 +1723,7 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
* @param {string} cta - The call to action text.
|
||||
* @param {object} text - The text object.
|
||||
* @param {string} key - The key of the texture to use as the share image.
|
||||
* @param {(string|integer)} [frame] - The frame of the texture to use as the share image. Set to `null` if you don't require a frame, but do need to set session data.
|
||||
* @param {?(string|integer)} frame - The frame of the texture to use as the share image. Set to `null` if you don't require a frame, but do need to set session data.
|
||||
* @param {string} template - The update template key.
|
||||
* @param {object} updateData - The update data object payload.
|
||||
*
|
||||
|
@ -1684,7 +1745,7 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
* @param {string} cta - The call to action text.
|
||||
* @param {object} text - The text object.
|
||||
* @param {string} key - The key of the texture to use as the share image.
|
||||
* @param {(string|integer)} [frame] - The frame of the texture to use as the share image. Set to `null` if you don't require a frame, but do need to set session data.
|
||||
* @param {?(string|integer)} frame - The frame of the texture to use as the share image. Set to `null` if you don't require a frame, but do need to set session data.
|
||||
* @param {string} template - The update template key.
|
||||
* @param {object} updateData - The update data object payload.
|
||||
*
|
||||
|
@ -2060,7 +2121,7 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
{
|
||||
var ad = this.ads[i];
|
||||
|
||||
if (ad.placementID === placementID)
|
||||
if (ad.placementID === placementID && !ad.shown)
|
||||
{
|
||||
ad.instance.showAsync().then(function ()
|
||||
{
|
||||
|
@ -2109,7 +2170,7 @@ var FacebookInstantGamesPlugin = new Class({
|
|||
{
|
||||
var ad = this.ads[i];
|
||||
|
||||
if (ad.placementID === placementID && ad.video)
|
||||
if (ad.placementID === placementID && ad.video && !ad.shown)
|
||||
{
|
||||
ad.instance.showAsync().then(function ()
|
||||
{
|
||||
|
|
|
@ -15,9 +15,10 @@ var LeaderboardScore = require('./LeaderboardScore');
|
|||
* You do not need to instantiate this class directly, it will be created when you use the
|
||||
* `getLeaderboard()` method of the main plugin.
|
||||
*
|
||||
* @class Leaderboard
|
||||
* @memberOf Phaser.FacebookInstantGamesPlugin
|
||||
* @class FacebookInstantGamesLeaderboard
|
||||
* @memberOf Phaser
|
||||
* @constructor
|
||||
* @extends Phaser.Events.EventEmitter
|
||||
* @since 3.13.0
|
||||
*
|
||||
* @param {Phaser.FacebookInstantGamesPlugin} plugin - A reference to the Facebook Instant Games Plugin.
|
||||
|
@ -36,7 +37,7 @@ var Leaderboard = new Class({
|
|||
/**
|
||||
* A reference to the Facebook Instant Games Plugin.
|
||||
*
|
||||
* @name Phaser.FacebookInstantGamesPlugin.Leaderboard#plugin
|
||||
* @name Phaser.FacebookInstantGamesLeaderboard#plugin
|
||||
* @type {Phaser.FacebookInstantGamesPlugin}
|
||||
* @since 3.13.0
|
||||
*/
|
||||
|
@ -45,7 +46,7 @@ var Leaderboard = new Class({
|
|||
/**
|
||||
* An Instant Game leaderboard instance.
|
||||
*
|
||||
* @name Phaser.FacebookInstantGamesPlugin.Leaderboard#ref
|
||||
* @name Phaser.FacebookInstantGamesLeaderboard#ref
|
||||
* @type {any}
|
||||
* @since 3.13.0
|
||||
*/
|
||||
|
@ -54,7 +55,7 @@ var Leaderboard = new Class({
|
|||
/**
|
||||
* The name of the leaderboard.
|
||||
*
|
||||
* @name Phaser.FacebookInstantGamesPlugin.Leaderboard#name
|
||||
* @name Phaser.FacebookInstantGamesLeaderboard#name
|
||||
* @type {string}
|
||||
* @since 3.13.0
|
||||
*/
|
||||
|
@ -63,7 +64,7 @@ var Leaderboard = new Class({
|
|||
/**
|
||||
* The ID of the context that the leaderboard is associated with, or null if the leaderboard is not tied to a particular context.
|
||||
*
|
||||
* @name Phaser.FacebookInstantGamesPlugin.Leaderboard#contextID
|
||||
* @name Phaser.FacebookInstantGamesLeaderboard#contextID
|
||||
* @type {string}
|
||||
* @since 3.13.0
|
||||
*/
|
||||
|
@ -73,7 +74,7 @@ var Leaderboard = new Class({
|
|||
* The total number of player entries in the leaderboard.
|
||||
* This value defaults to zero. Populate it via the `getEntryCount()` method.
|
||||
*
|
||||
* @name Phaser.FacebookInstantGamesPlugin.Leaderboard#entryCount
|
||||
* @name Phaser.FacebookInstantGamesLeaderboard#entryCount
|
||||
* @type {integer}
|
||||
* @since 3.13.0
|
||||
*/
|
||||
|
@ -83,7 +84,7 @@ var Leaderboard = new Class({
|
|||
* The players score object.
|
||||
* This value defaults to `null`. Populate it via the `getPlayerScore()` method.
|
||||
*
|
||||
* @name Phaser.FacebookInstantGamesPlugin.Leaderboard#playerScore
|
||||
* @name Phaser.FacebookInstantGamesLeaderboard#playerScore
|
||||
* @type {LeaderboardScore}
|
||||
* @since 3.13.0
|
||||
*/
|
||||
|
@ -94,7 +95,7 @@ var Leaderboard = new Class({
|
|||
* This value defaults to an empty array. Populate it via the `getScores()` method.
|
||||
* The contents of this array are reset each time `getScores()` is called.
|
||||
*
|
||||
* @name Phaser.FacebookInstantGamesPlugin.Leaderboard#scores
|
||||
* @name Phaser.FacebookInstantGamesLeaderboard#scores
|
||||
* @type {LeaderboardScore[]}
|
||||
* @since 3.13.0
|
||||
*/
|
||||
|
@ -110,7 +111,7 @@ var Leaderboard = new Class({
|
|||
*
|
||||
* When the call completes this Leaderboard will emit the `getentrycount` event along with the count and name of the Leaderboard.
|
||||
*
|
||||
* @method Phaser.FacebookInstantGamesPlugin.Leaderboard#getEntryCount
|
||||
* @method Phaser.FacebookInstantGamesLeaderboard#getEntryCount
|
||||
* @since 3.13.0
|
||||
*
|
||||
* @return {this} This Leaderboard instance.
|
||||
|
@ -143,7 +144,7 @@ var Leaderboard = new Class({
|
|||
*
|
||||
* If the save fails the event will send `null` as the score value.
|
||||
*
|
||||
* @method Phaser.FacebookInstantGamesPlugin.Leaderboard#setScore
|
||||
* @method Phaser.FacebookInstantGamesLeaderboard#setScore
|
||||
* @since 3.13.0
|
||||
*
|
||||
* @param {integer} score - The new score for the player. Must be a 64-bit integer number.
|
||||
|
@ -194,7 +195,7 @@ var Leaderboard = new Class({
|
|||
*
|
||||
* If the player has not yet saved a score, the event will send `null` as the score value, and `playerScore` will be set to `null` as well.
|
||||
*
|
||||
* @method Phaser.FacebookInstantGamesPlugin.Leaderboard#getPlayerScore
|
||||
* @method Phaser.FacebookInstantGamesLeaderboard#getPlayerScore
|
||||
* @since 3.13.0
|
||||
*
|
||||
* @return {this} This Leaderboard instance.
|
||||
|
@ -233,7 +234,7 @@ var Leaderboard = new Class({
|
|||
*
|
||||
* When the call completes this Leaderboard will emit the `getscores` event along with an array of LeaderboardScore entries and the name of the Leaderboard.
|
||||
*
|
||||
* @method Phaser.FacebookInstantGamesPlugin.Leaderboard#getScores
|
||||
* @method Phaser.FacebookInstantGamesLeaderboard#getScores
|
||||
* @since 3.13.0
|
||||
*
|
||||
* @param {integer} [count=10] - The number of entries to attempt to fetch from the leaderboard. Currently, up to a maximum of 100 entries may be fetched per query.
|
||||
|
@ -248,7 +249,7 @@ var Leaderboard = new Class({
|
|||
|
||||
var _this = this;
|
||||
|
||||
this.ref.getEntriesAsync().then(function (entries)
|
||||
this.ref.getEntriesAsync(count, offset).then(function (entries)
|
||||
{
|
||||
_this.scores = [];
|
||||
|
||||
|
@ -274,19 +275,13 @@ var Leaderboard = new Class({
|
|||
*
|
||||
* When the call completes this Leaderboard will emit the `getconnectedscores` event along with an array of LeaderboardScore entries and the name of the Leaderboard.
|
||||
*
|
||||
* @method Phaser.FacebookInstantGamesPlugin.Leaderboard#getConnectedScores
|
||||
* @method Phaser.FacebookInstantGamesLeaderboard#getConnectedScores
|
||||
* @since 3.16.0
|
||||
*
|
||||
* @param {integer} [count=10] - The number of entries to attempt to fetch from the leaderboard. Currently, up to a maximum of 100 entries may be fetched per query.
|
||||
* @param {integer} [offset=0] - The offset from the top of the leaderboard that entries will be fetched from.
|
||||
*
|
||||
* @return {this} This Leaderboard instance.
|
||||
*/
|
||||
getConnectedScores: function (count, offset)
|
||||
getConnectedScores: function ()
|
||||
{
|
||||
if (count === undefined) { count = 10; }
|
||||
if (offset === undefined) { offset = 0; }
|
||||
|
||||
var _this = this;
|
||||
|
||||
this.ref.getConnectedPlayerEntriesAsync().then(function (entries)
|
||||
|
|
|
@ -11,3 +11,10 @@ else
|
|||
{
|
||||
console.log('Copy-to-Examples failed: Phaser 3 Examples not present at ../phaser3-examples');
|
||||
}
|
||||
|
||||
dest = '../100-phaser3-snippets/public/libs/';
|
||||
|
||||
if (fs.existsSync(dest))
|
||||
{
|
||||
fs.copySync(source, dest, { overwrite: true });
|
||||
}
|
||||
|
|
29737
plugins/spine/dist/SpineCanvasPlugin.js
vendored
Normal file
29737
plugins/spine/dist/SpineCanvasPlugin.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
plugins/spine/dist/SpineCanvasPlugin.min.js
vendored
Normal file
1
plugins/spine/dist/SpineCanvasPlugin.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
32230
plugins/spine/dist/SpinePlugin.js
vendored
Normal file
32230
plugins/spine/dist/SpinePlugin.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
plugins/spine/dist/SpinePlugin.min.js
vendored
Normal file
1
plugins/spine/dist/SpinePlugin.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
33307
plugins/spine/dist/SpinePluginDebug.js
vendored
Normal file
33307
plugins/spine/dist/SpinePluginDebug.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
plugins/spine/dist/SpinePluginDebug.js.map
vendored
Normal file
1
plugins/spine/dist/SpinePluginDebug.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
44535
plugins/spine/dist/SpineWebGLPlugin.js
vendored
44535
plugins/spine/dist/SpineWebGLPlugin.js
vendored
File diff suppressed because it is too large
Load diff
1
plugins/spine/dist/SpineWebGLPlugin.js.map
vendored
1
plugins/spine/dist/SpineWebGLPlugin.js.map
vendored
File diff suppressed because one or more lines are too long
1
plugins/spine/dist/SpineWebGLPlugin.min.js
vendored
Normal file
1
plugins/spine/dist/SpineWebGLPlugin.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,190 +0,0 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
var Class = require('../../../src/utils/Class');
|
||||
var ScenePlugin = require('../../../src/plugins/ScenePlugin');
|
||||
var SpineFile = require('./SpineFile');
|
||||
var SpineGameObject = require('./gameobject/SpineGameObject');
|
||||
|
||||
var runtime;
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* TODO
|
||||
*
|
||||
* @class SpinePlugin
|
||||
* @extends Phaser.Plugins.ScenePlugin
|
||||
* @constructor
|
||||
* @since 3.16.0
|
||||
*
|
||||
* @param {Phaser.Scene} scene - A reference to the Scene that has installed this plugin.
|
||||
* @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Phaser Plugin Manager.
|
||||
*/
|
||||
var SpinePlugin = new Class({
|
||||
|
||||
Extends: ScenePlugin,
|
||||
|
||||
initialize:
|
||||
|
||||
function SpinePlugin (scene, pluginManager, SpineRuntime)
|
||||
{
|
||||
console.log('BaseSpinePlugin created');
|
||||
|
||||
ScenePlugin.call(this, scene, pluginManager);
|
||||
|
||||
var game = pluginManager.game;
|
||||
|
||||
// Create a custom cache to store the spine data (.atlas files)
|
||||
this.cache = game.cache.addCustom('spine');
|
||||
|
||||
this.json = game.cache.json;
|
||||
|
||||
this.textures = game.textures;
|
||||
|
||||
this.skeletonRenderer;
|
||||
|
||||
this.drawDebug = false;
|
||||
|
||||
// Register our file type
|
||||
pluginManager.registerFileType('spine', this.spineFileCallback, scene);
|
||||
|
||||
// Register our game object
|
||||
pluginManager.registerGameObject('spine', this.createSpineFactory(this));
|
||||
|
||||
runtime = SpineRuntime;
|
||||
},
|
||||
|
||||
spineFileCallback: function (key, jsonURL, atlasURL, 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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
multifile = new SpineFile(this, key, jsonURL, atlasURL, jsonXhrSettings, atlasXhrSettings);
|
||||
|
||||
this.addFile(multifile.files);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a new Spine Game Object and adds it to the Scene.
|
||||
*
|
||||
* @method Phaser.GameObjects.GameObjectFactory#spineFactory
|
||||
* @since 3.16.0
|
||||
*
|
||||
* @param {number} x - The horizontal position of this Game Object.
|
||||
* @param {number} y - The vertical position of this Game Object.
|
||||
* @param {string} texture - The key 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.Spine} The Game Object that was created.
|
||||
*/
|
||||
createSpineFactory: function (plugin)
|
||||
{
|
||||
var callback = function (x, y, key, animationName, loop)
|
||||
{
|
||||
var spineGO = new SpineGameObject(this.scene, plugin, x, y, key, animationName, loop);
|
||||
|
||||
this.displayList.add(spineGO);
|
||||
this.updateList.add(spineGO);
|
||||
|
||||
return spineGO;
|
||||
};
|
||||
|
||||
return callback;
|
||||
},
|
||||
|
||||
getRuntime: function ()
|
||||
{
|
||||
return runtime;
|
||||
},
|
||||
|
||||
createSkeleton: function (key, skeletonJSON)
|
||||
{
|
||||
var atlas = this.getAtlas(key);
|
||||
|
||||
var atlasLoader = new runtime.AtlasAttachmentLoader(atlas);
|
||||
|
||||
var skeletonJson = new runtime.SkeletonJson(atlasLoader);
|
||||
|
||||
var data = (skeletonJSON) ? skeletonJSON : this.json.get(key);
|
||||
|
||||
var skeletonData = skeletonJson.readSkeletonData(data);
|
||||
|
||||
var skeleton = new runtime.Skeleton(skeletonData);
|
||||
|
||||
return { skeletonData: skeletonData, skeleton: skeleton };
|
||||
},
|
||||
|
||||
getBounds: function (skeleton)
|
||||
{
|
||||
var offset = new runtime.Vector2();
|
||||
var size = new runtime.Vector2();
|
||||
|
||||
skeleton.getBounds(offset, size, []);
|
||||
|
||||
return { offset: offset, size: size };
|
||||
},
|
||||
|
||||
createAnimationState: function (skeleton)
|
||||
{
|
||||
var stateData = new runtime.AnimationStateData(skeleton.data);
|
||||
|
||||
var state = new runtime.AnimationState(stateData);
|
||||
|
||||
return { stateData: stateData, state: state };
|
||||
},
|
||||
|
||||
/**
|
||||
* 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 Camera3DPlugin#shutdown
|
||||
* @private
|
||||
* @since 3.0.0
|
||||
*/
|
||||
shutdown: function ()
|
||||
{
|
||||
var eventEmitter = this.systems.events;
|
||||
|
||||
eventEmitter.off('update', this.update, this);
|
||||
eventEmitter.off('shutdown', this.shutdown, this);
|
||||
|
||||
this.removeAll();
|
||||
},
|
||||
|
||||
/**
|
||||
* The Scene that owns this plugin is being destroyed.
|
||||
* We need to shutdown and then kill off all external references.
|
||||
*
|
||||
* @method Camera3DPlugin#destroy
|
||||
* @private
|
||||
* @since 3.0.0
|
||||
*/
|
||||
destroy: function ()
|
||||
{
|
||||
this.shutdown();
|
||||
|
||||
this.pluginManager = null;
|
||||
this.game = null;
|
||||
this.scene = null;
|
||||
this.systems = null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = SpinePlugin;
|
|
@ -1,63 +0,0 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
var Class = require('../../../src/utils/Class');
|
||||
var BaseSpinePlugin = require('./BaseSpinePlugin');
|
||||
var SpineCanvas = require('SpineCanvas');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Just the Canvas Runtime.
|
||||
*
|
||||
* @class SpinePlugin
|
||||
* @extends Phaser.Plugins.ScenePlugin
|
||||
* @constructor
|
||||
* @since 3.16.0
|
||||
*
|
||||
* @param {Phaser.Scene} scene - A reference to the Scene that has installed this plugin.
|
||||
* @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Phaser Plugin Manager.
|
||||
*/
|
||||
var SpineCanvasPlugin = new Class({
|
||||
|
||||
Extends: BaseSpinePlugin,
|
||||
|
||||
initialize:
|
||||
|
||||
function SpineCanvasPlugin (scene, pluginManager)
|
||||
{
|
||||
console.log('SpineCanvasPlugin created');
|
||||
|
||||
BaseSpinePlugin.call(this, scene, pluginManager, SpineCanvas);
|
||||
},
|
||||
|
||||
boot: function ()
|
||||
{
|
||||
this.skeletonRenderer = new SpineCanvas.canvas.SkeletonRenderer(this.game.context);
|
||||
},
|
||||
|
||||
getAtlas: function (key)
|
||||
{
|
||||
var atlasData = this.cache.get(key);
|
||||
|
||||
if (!atlasData)
|
||||
{
|
||||
console.warn('No atlas data for: ' + key);
|
||||
return;
|
||||
}
|
||||
|
||||
var textures = this.textures;
|
||||
|
||||
var atlas = new SpineCanvas.TextureAtlas(atlasData, function (path)
|
||||
{
|
||||
return new SpineCanvas.canvas.CanvasTexture(textures.get(path).getSourceImage());
|
||||
});
|
||||
|
||||
return atlas;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = SpineCanvasPlugin;
|
|
@ -39,10 +39,11 @@ var TextFile = require('../../../src/loader/filetypes/TextFile.js');
|
|||
* @constructor
|
||||
*
|
||||
* @param {Phaser.Loader.LoaderPlugin} loader - A reference to the Loader that is responsible for this file.
|
||||
* @param {(string|Phaser.Loader.FileTypes.UnityAtlasFileConfig)} key - The key to use for this file, or a file configuration object.
|
||||
* @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `<key>.png`, i.e. if `key` was "alien" then the URL will be "alien.png".
|
||||
* @param {(string|Phaser.Loader.FileTypes.SpineFileConfig)} key - The key to use for this file, or a file configuration object.
|
||||
* @param {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".
|
||||
* @param {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".
|
||||
* @param {XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings.
|
||||
* @param {boolean} [preMultipliedAlpha=false] - Do the textures contain pre-multiplied alpha or not?
|
||||
* @param {XHRSettingsObject} [jsonXhrSettings] - An XHR Settings configuration object for the json file. Used in replacement of the Loaders default XHR Settings.
|
||||
* @param {XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas data file. Used in replacement of the Loaders default XHR Settings.
|
||||
*/
|
||||
var SpineFile = new Class({
|
||||
|
@ -51,10 +52,15 @@ var SpineFile = new Class({
|
|||
|
||||
initialize:
|
||||
|
||||
function SpineFile (loader, key, jsonURL, atlasURL, jsonXhrSettings, atlasXhrSettings)
|
||||
function SpineFile (loader, key, jsonURL, atlasURL, preMultipliedAlpha, jsonXhrSettings, atlasXhrSettings)
|
||||
{
|
||||
var i;
|
||||
var json;
|
||||
var atlas;
|
||||
var files = [];
|
||||
var cache = loader.cacheManager.custom.spine;
|
||||
|
||||
// atlas can be an array of atlas files, not just a single one
|
||||
|
||||
if (IsPlainObject(key))
|
||||
{
|
||||
|
@ -69,29 +75,58 @@ var SpineFile = new Class({
|
|||
xhrSettings: GetFastValue(config, 'jsonXhrSettings')
|
||||
});
|
||||
|
||||
atlas = new TextFile(loader, {
|
||||
key: key,
|
||||
url: GetFastValue(config, 'atlasURL'),
|
||||
extension: GetFastValue(config, 'atlasExtension', 'atlas'),
|
||||
xhrSettings: GetFastValue(config, 'atlasXhrSettings')
|
||||
});
|
||||
atlasURL = GetFastValue(config, 'atlasURL');
|
||||
preMultipliedAlpha = GetFastValue(config, 'preMultipliedAlpha');
|
||||
|
||||
if (!Array.isArray(atlasURL))
|
||||
{
|
||||
atlasURL = [ atlasURL ];
|
||||
}
|
||||
|
||||
for (i = 0; i < atlasURL.length; i++)
|
||||
{
|
||||
atlas = new TextFile(loader, {
|
||||
key: key,
|
||||
url: atlasURL[i],
|
||||
extension: GetFastValue(config, 'atlasExtension', 'atlas'),
|
||||
xhrSettings: GetFastValue(config, 'atlasXhrSettings')
|
||||
});
|
||||
|
||||
atlas.cache = cache;
|
||||
|
||||
files.push(atlas);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
json = new JSONFile(loader, key, jsonURL, jsonXhrSettings);
|
||||
atlas = new TextFile(loader, key, atlasURL, atlasXhrSettings);
|
||||
}
|
||||
|
||||
atlas.cache = loader.cacheManager.custom.spine;
|
||||
|
||||
MultiFile.call(this, loader, 'spine', key, [ json, atlas ]);
|
||||
if (!Array.isArray(atlasURL))
|
||||
{
|
||||
atlasURL = [ atlasURL ];
|
||||
}
|
||||
|
||||
for (i = 0; i < atlasURL.length; i++)
|
||||
{
|
||||
atlas = new TextFile(loader, key + '_' + i, atlasURL[i], atlasXhrSettings);
|
||||
atlas.cache = cache;
|
||||
|
||||
files.push(atlas);
|
||||
}
|
||||
}
|
||||
|
||||
files.unshift(json);
|
||||
|
||||
MultiFile.call(this, loader, 'spine', key, files);
|
||||
|
||||
this.config.preMultipliedAlpha = preMultipliedAlpha;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called by each File when it finishes loading.
|
||||
*
|
||||
* @method Phaser.Loader.MultiFile#onFileComplete
|
||||
* @since 3.7.0
|
||||
* @method Phaser.Loader.FileTypes.SpineFile#onFileComplete
|
||||
* @since 3.19.0
|
||||
*
|
||||
* @param {Phaser.Loader.File} file - The File that has completed processing.
|
||||
*/
|
||||
|
@ -130,9 +165,9 @@ var SpineFile = new Class({
|
|||
var currentPath = loader.path;
|
||||
var currentPrefix = loader.prefix;
|
||||
|
||||
var baseURL = GetFastValue(config, 'baseURL', currentBaseURL);
|
||||
var path = GetFastValue(config, 'path', currentPath);
|
||||
var prefix = GetFastValue(config, 'prefix', currentPrefix);
|
||||
var baseURL = GetFastValue(config, 'baseURL', this.baseURL);
|
||||
var path = GetFastValue(config, 'path', this.path);
|
||||
var prefix = GetFastValue(config, 'prefix', this.prefix);
|
||||
var textureXhrSettings = GetFastValue(config, 'textureXhrSettings');
|
||||
|
||||
loader.setBaseURL(baseURL);
|
||||
|
@ -143,7 +178,7 @@ var SpineFile = new Class({
|
|||
{
|
||||
var textureURL = textures[i];
|
||||
|
||||
var key = '_SP_' + textureURL;
|
||||
var key = 'SP' + this.multiKeyIndex + '_' + textureURL;
|
||||
|
||||
var image = new ImageFile(loader, key, textureURL, textureXhrSettings);
|
||||
|
||||
|
@ -164,7 +199,7 @@ var SpineFile = new Class({
|
|||
* Adds this file to its target cache upon successful loading and processing.
|
||||
*
|
||||
* @method Phaser.Loader.FileTypes.SpineFile#addToCache
|
||||
* @since 3.16.0
|
||||
* @since 3.19.0
|
||||
*/
|
||||
addToCache: function ()
|
||||
{
|
||||
|
@ -174,152 +209,41 @@ var SpineFile = new Class({
|
|||
|
||||
fileJSON.addToCache();
|
||||
|
||||
var fileText = this.files[1];
|
||||
var atlasCache;
|
||||
var atlasKey = '';
|
||||
var combinedAtlasData = '';
|
||||
var preMultipliedAlpha = (this.config.preMultipliedAlpha) ? true : false;
|
||||
|
||||
fileText.addToCache();
|
||||
|
||||
for (var i = 2; i < this.files.length; i++)
|
||||
for (var i = 1; i < this.files.length; i++)
|
||||
{
|
||||
var file = this.files[i];
|
||||
|
||||
var key = file.key.substr(4).trim();
|
||||
if (file.type === 'text')
|
||||
{
|
||||
atlasKey = file.key.substr(0, file.key.length - 2);
|
||||
|
||||
this.loader.textureManager.addImage(key, file.data);
|
||||
atlasCache = file.cache;
|
||||
|
||||
combinedAtlasData = combinedAtlasData.concat(file.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
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 });
|
||||
|
||||
this.complete = true;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Adds a Unity YAML based Texture Atlas, or array of atlases, 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 ()
|
||||
* {
|
||||
* this.load.unityAtlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.txt');
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* The file is **not** loaded right away. It is added to a queue ready to be loaded either when the loader starts,
|
||||
* or if it's already running, when the next free load slot becomes available. This happens automatically if you
|
||||
* are calling this from within the Scene's `preload` method, or a related callback. Because the file is queued
|
||||
* it means you cannot use the file immediately after calling this method, but must wait for the file to complete.
|
||||
* 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 atlas data to be provided in a YAML formatted text file as exported from Unity.
|
||||
*
|
||||
* Phaser can load all common image types: png, jpg, gif and any other format the browser can natively handle.
|
||||
*
|
||||
* The key must be a unique String. It is used to add the file to the global Texture Manager upon a successful load.
|
||||
* The key should be unique both in terms of files being loaded and files already present in the Texture Manager.
|
||||
* Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file
|
||||
* then remove it from the Texture Manager first, before loading a new one.
|
||||
*
|
||||
* Instead of passing arguments you can pass a configuration object, such as:
|
||||
*
|
||||
* ```javascript
|
||||
* this.load.unityAtlas({
|
||||
* key: 'mainmenu',
|
||||
* textureURL: 'images/MainMenu.png',
|
||||
* atlasURL: 'images/MainMenu.txt'
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* See the documentation for `Phaser.Loader.FileTypes.SpineFileConfig` for more details.
|
||||
*
|
||||
* Once the atlas has finished loading you can use frames from it as textures for a Game Object by referencing its key:
|
||||
*
|
||||
* ```javascript
|
||||
* this.load.unityAtlas('mainmenu', 'images/MainMenu.png', 'images/MainMenu.json');
|
||||
* // and later in your game ...
|
||||
* this.add.image(x, y, 'mainmenu', 'background');
|
||||
* ```
|
||||
*
|
||||
* To get a list of all available frames within an atlas please consult your Texture Atlas software.
|
||||
*
|
||||
* If you have specified a prefix in the loader, via `Loader.setPrefix` then this value will be prepended to this files
|
||||
* key. For example, if the prefix was `MENU.` and the key was `Background` the final key will be `MENU.Background` and
|
||||
* this is what you would use to retrieve the image from the Texture Manager.
|
||||
*
|
||||
* The URL can be relative or absolute. If the URL is relative the `Loader.baseURL` and `Loader.path` values will be prepended to it.
|
||||
*
|
||||
* If the URL isn't specified the Loader will take the key and create a filename from that. For example if the key is "alien"
|
||||
* and no URL is given then the Loader will set the URL to be "alien.png". It will always add `.png` as the extension, although
|
||||
* this can be overridden if using an object instead of method arguments. If you do not desire this action then provide a URL.
|
||||
*
|
||||
* Phaser also supports the automatic loading of associated normal maps. If you have a normal map to go with this image,
|
||||
* then you can specify it by providing an array as the `url` where the second element is the normal map:
|
||||
*
|
||||
* ```javascript
|
||||
* this.load.unityAtlas('mainmenu', [ 'images/MainMenu.png', 'images/MainMenu-n.png' ], 'images/MainMenu.txt');
|
||||
* ```
|
||||
*
|
||||
* Or, if you are using a config object use the `normalMap` property:
|
||||
*
|
||||
* ```javascript
|
||||
* this.load.unityAtlas({
|
||||
* key: 'mainmenu',
|
||||
* textureURL: 'images/MainMenu.png',
|
||||
* normalMap: 'images/MainMenu-n.png',
|
||||
* atlasURL: 'images/MainMenu.txt'
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* The normal map file is subject to the same conditions as the image file with regard to the path, baseURL, CORs and XHR Settings.
|
||||
* Normal maps are a WebGL only feature.
|
||||
*
|
||||
* Note: The ability to load this type of file will only be available if the Unity Atlas File type has been built into Phaser.
|
||||
* It is available in the default build but can be excluded from custom builds.
|
||||
*
|
||||
* @method Phaser.Loader.LoaderPlugin#spine
|
||||
* @fires Phaser.Loader.LoaderPlugin#addFileEvent
|
||||
* @since 3.16.0
|
||||
*
|
||||
* @param {(string|Phaser.Loader.FileTypes.SpineFileConfig|Phaser.Loader.FileTypes.SpineFileConfig[])} key - The key to use for this file, or a file configuration object, or array of them.
|
||||
* @param {string|string[]} [textureURL] - The absolute or relative URL to load the texture image file from. If undefined or `null` it will be set to `<key>.png`, i.e. if `key` was "alien" then the URL will be "alien.png".
|
||||
* @param {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".
|
||||
* @param {XHRSettingsObject} [textureXhrSettings] - An XHR Settings configuration object for the atlas image file. Used in replacement of the Loaders default XHR Settings.
|
||||
* @param {XHRSettingsObject} [atlasXhrSettings] - An XHR Settings configuration object for the atlas data file. Used in replacement of the Loaders default XHR Settings.
|
||||
*
|
||||
* @return {Phaser.Loader.LoaderPlugin} The Loader instance.
|
||||
FileTypesManager.register('spine', function (key, jsonURL, atlasURL, jsonXhrSettings, atlasXhrSettings)
|
||||
{
|
||||
var multifile;
|
||||
|
||||
// Supports an Object file definition in the key argument
|
||||
// Or an array of objects in the key argument
|
||||
// Or a single entry where all arguments have been defined
|
||||
|
||||
if (Array.isArray(key))
|
||||
{
|
||||
for (var i = 0; i < key.length; i++)
|
||||
{
|
||||
multifile = new SpineFile(this, key[i]);
|
||||
|
||||
this.addFile(multifile.files);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
multifile = new SpineFile(this, key, jsonURL, atlasURL, jsonXhrSettings, atlasXhrSettings);
|
||||
|
||||
this.addFile(multifile.files);
|
||||
}
|
||||
|
||||
return this;
|
||||
});
|
||||
*/
|
||||
|
||||
module.exports = SpineFile;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,90 +0,0 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
var Class = require('../../../src/utils/Class');
|
||||
var BaseSpinePlugin = require('./BaseSpinePlugin');
|
||||
var SpineWebGL = require('SpineWebGL');
|
||||
var Matrix4 = require('../../../src/math/Matrix4');
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Just the WebGL Runtime.
|
||||
*
|
||||
* @class SpinePlugin
|
||||
* @extends Phaser.Plugins.ScenePlugin
|
||||
* @constructor
|
||||
* @since 3.16.0
|
||||
*
|
||||
* @param {Phaser.Scene} scene - A reference to the Scene that has installed this plugin.
|
||||
* @param {Phaser.Plugins.PluginManager} pluginManager - A reference to the Phaser Plugin Manager.
|
||||
*/
|
||||
var SpineWebGLPlugin = new Class({
|
||||
|
||||
Extends: BaseSpinePlugin,
|
||||
|
||||
initialize:
|
||||
|
||||
function SpineWebGLPlugin (scene, pluginManager)
|
||||
{
|
||||
console.log('SpineWebGLPlugin created');
|
||||
|
||||
BaseSpinePlugin.call(this, scene, pluginManager, SpineWebGL);
|
||||
|
||||
this.gl;
|
||||
this.mvp;
|
||||
this.shader;
|
||||
this.batcher;
|
||||
this.debugRenderer;
|
||||
this.debugShader;
|
||||
},
|
||||
|
||||
boot: function ()
|
||||
{
|
||||
var gl = this.game.renderer.gl;
|
||||
|
||||
this.gl = gl;
|
||||
|
||||
this.mvp = new Matrix4();
|
||||
|
||||
// Create a simple shader, mesh, model-view-projection matrix and SkeletonRenderer.
|
||||
this.shader = SpineWebGL.webgl.Shader.newTwoColoredTextured(gl);
|
||||
this.batcher = new SpineWebGL.webgl.PolygonBatcher(gl);
|
||||
|
||||
this.skeletonRenderer = new SpineWebGL.webgl.SkeletonRenderer(gl);
|
||||
this.skeletonRenderer.premultipliedAlpha = true;
|
||||
|
||||
this.shapes = new SpineWebGL.webgl.ShapeRenderer(gl);
|
||||
|
||||
this.debugRenderer = new SpineWebGL.webgl.SkeletonDebugRenderer(gl);
|
||||
|
||||
this.debugShader = SpineWebGL.webgl.Shader.newColored(gl);
|
||||
},
|
||||
|
||||
getAtlas: function (key)
|
||||
{
|
||||
var atlasData = this.cache.get(key);
|
||||
|
||||
if (!atlasData)
|
||||
{
|
||||
console.warn('No atlas data for: ' + key);
|
||||
return;
|
||||
}
|
||||
|
||||
var textures = this.textures;
|
||||
|
||||
var gl = this.game.renderer.gl;
|
||||
|
||||
var atlas = new SpineWebGL.TextureAtlas(atlasData, function (path)
|
||||
{
|
||||
return new SpineWebGL.webgl.GLTexture(gl, textures.get(path).getSourceImage());
|
||||
});
|
||||
|
||||
return atlas;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = SpineWebGLPlugin;
|
13
plugins/spine/src/events/COMPLETE_EVENT.js
Normal file
13
plugins/spine/src/events/COMPLETE_EVENT.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Complete Event.
|
||||
*
|
||||
* @event SpinePluginEvents#COMPLETE
|
||||
* @since 3.19.0
|
||||
*/
|
||||
module.exports = 'complete';
|
13
plugins/spine/src/events/DISPOSE_EVENT.js
Normal file
13
plugins/spine/src/events/DISPOSE_EVENT.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Dispose Event.
|
||||
*
|
||||
* @event SpinePluginEvents#DISPOSE
|
||||
* @since 3.19.0
|
||||
*/
|
||||
module.exports = 'dispose';
|
13
plugins/spine/src/events/END_EVENT.js
Normal file
13
plugins/spine/src/events/END_EVENT.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The End Event.
|
||||
*
|
||||
* @event SpinePluginEvents#END
|
||||
* @since 3.19.0
|
||||
*/
|
||||
module.exports = 'end';
|
13
plugins/spine/src/events/EVENT_EVENT.js
Normal file
13
plugins/spine/src/events/EVENT_EVENT.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Custom Event Event.
|
||||
*
|
||||
* @event SpinePluginEvents#EVENT
|
||||
* @since 3.19.0
|
||||
*/
|
||||
module.exports = 'event';
|
13
plugins/spine/src/events/INTERRUPTED_EVENT.js
Normal file
13
plugins/spine/src/events/INTERRUPTED_EVENT.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Interrupted Event.
|
||||
*
|
||||
* @event SpinePluginEvents#INTERRUPTED
|
||||
* @since 3.19.0
|
||||
*/
|
||||
module.exports = 'interrupted';
|
13
plugins/spine/src/events/START_EVENT.js
Normal file
13
plugins/spine/src/events/START_EVENT.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Start Event.
|
||||
*
|
||||
* @event SpinePluginEvents#START
|
||||
* @since 3.19.0
|
||||
*/
|
||||
module.exports = 'start';
|
20
plugins/spine/src/events/index.js
Normal file
20
plugins/spine/src/events/index.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @namespace SpinePluginEvents
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
|
||||
COMPLETE: require('./COMPLETE_EVENT'),
|
||||
DISPOSE: require('./DISPOSE_EVENT'),
|
||||
END: require('./END_EVENT'),
|
||||
EVENT: require('./EVENT_EVENT'),
|
||||
INTERRUPTED: require('./INTERRUPTED_EVENT'),
|
||||
START: require('./START_EVENT')
|
||||
|
||||
};
|
File diff suppressed because it is too large
Load diff
|
@ -1,22 +1,24 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
var SetTransform = require('../../../../src/renderer/canvas/utils/SetTransform');
|
||||
var CounterClockwise = require('../../../../src/math/angle/CounterClockwise');
|
||||
var RadToDeg = require('../../../../src/math/RadToDeg');
|
||||
var Wrap = require('../../../../src/math/Wrap');
|
||||
|
||||
/**
|
||||
* Renders this Game Object with the Canvas Renderer to the given Camera.
|
||||
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
||||
* This method should not be called directly. It is a utility function of the Render module.
|
||||
*
|
||||
* @method Phaser.GameObjects.SpineGameObject#renderCanvas
|
||||
* @since 3.16.0
|
||||
* @method SpineGameObject#renderCanvas
|
||||
* @since 3.19.0
|
||||
* @private
|
||||
*
|
||||
* @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer.
|
||||
* @param {Phaser.GameObjects.SpineGameObject} src - The Game Object being rendered in this call.
|
||||
* @param {SpineGameObject} src - The Game Object being rendered in this call.
|
||||
* @param {number} interpolationPercentage - Reserved for future use and custom pipelines.
|
||||
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
|
||||
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
|
||||
|
@ -29,28 +31,94 @@ var SpineGameObjectCanvasRenderer = function (renderer, src, interpolationPercen
|
|||
var skeleton = src.skeleton;
|
||||
var skeletonRenderer = plugin.skeletonRenderer;
|
||||
|
||||
if (!skeleton || !SetTransform(renderer, context, src, camera, parentMatrix))
|
||||
var GameObjectRenderMask = 15;
|
||||
|
||||
var willRender = !(GameObjectRenderMask !== src.renderFlags || (src.cameraFilter !== 0 && (src.cameraFilter & camera.id)));
|
||||
|
||||
if (!skeleton || !willRender)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var camMatrix = renderer._tempMatrix1;
|
||||
var spriteMatrix = renderer._tempMatrix2;
|
||||
var calcMatrix = renderer._tempMatrix3;
|
||||
|
||||
spriteMatrix.applyITRS(src.x, src.y, src.rotation, Math.abs(src.scaleX), Math.abs(src.scaleY));
|
||||
|
||||
camMatrix.copyFrom(camera.matrix);
|
||||
|
||||
if (parentMatrix)
|
||||
{
|
||||
// Multiply the camera by the parent matrix
|
||||
camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY);
|
||||
|
||||
// Undo the camera scroll
|
||||
spriteMatrix.e = src.x;
|
||||
spriteMatrix.f = src.y;
|
||||
|
||||
// Multiply by the Sprite matrix, store result in calcMatrix
|
||||
camMatrix.multiply(spriteMatrix, calcMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteMatrix.e -= camera.scrollX * src.scrollFactorX;
|
||||
spriteMatrix.f -= camera.scrollY * src.scrollFactorY;
|
||||
|
||||
// Multiply by the Sprite matrix, store result in calcMatrix
|
||||
camMatrix.multiply(spriteMatrix, calcMatrix);
|
||||
}
|
||||
|
||||
skeleton.x = calcMatrix.tx;
|
||||
skeleton.y = calcMatrix.ty;
|
||||
|
||||
skeleton.scaleX = calcMatrix.scaleX;
|
||||
|
||||
// Inverse or we get upside-down skeletons
|
||||
skeleton.scaleY = calcMatrix.scaleY * -1;
|
||||
|
||||
if (src.scaleX < 0)
|
||||
{
|
||||
skeleton.scaleX *= -1;
|
||||
|
||||
src.root.rotation = RadToDeg(calcMatrix.rotationNormalized);
|
||||
}
|
||||
else
|
||||
{
|
||||
// +90 degrees to account for the difference in Spine vs. Phaser rotation
|
||||
src.root.rotation = Wrap(RadToDeg(CounterClockwise(calcMatrix.rotationNormalized)) + 90, 0, 360);
|
||||
}
|
||||
|
||||
if (src.scaleY < 0)
|
||||
{
|
||||
skeleton.scaleY *= -1;
|
||||
|
||||
if (src.scaleX < 0)
|
||||
{
|
||||
src.root.rotation -= (RadToDeg(calcMatrix.rotationNormalized) * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
src.root.rotation += (RadToDeg(calcMatrix.rotationNormalized) * 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (camera.renderToTexture)
|
||||
{
|
||||
skeleton.y = calcMatrix.ty;
|
||||
skeleton.scaleY *= -1;
|
||||
}
|
||||
|
||||
// Add autoUpdate option
|
||||
skeleton.updateWorldTransform();
|
||||
|
||||
skeletonRenderer.ctx = context;
|
||||
skeletonRenderer.debugRendering = (plugin.drawDebug || src.drawDebug);
|
||||
|
||||
context.save();
|
||||
|
||||
skeletonRenderer.draw(skeleton);
|
||||
|
||||
if (plugin.drawDebug || src.drawDebug)
|
||||
{
|
||||
context.strokeStyle = '#00ff00';
|
||||
context.beginPath();
|
||||
context.moveTo(-1000, 0);
|
||||
context.lineTo(1000, 0);
|
||||
context.moveTo(0, -1000);
|
||||
context.lineTo(0, 1000);
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
context.restore();
|
||||
};
|
||||
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
var SpineGameObject = require('./SpineGameObject');
|
||||
var GameObjectFactory = require('../../../../src/gameobjects/GameObjectFactory');
|
||||
|
||||
/**
|
||||
* Creates a new Spine Game Object Game Object and adds it to the Scene.
|
||||
*
|
||||
* Note: This method will only be available if the Spine Plugin has been built or loaded into Phaser.
|
||||
*
|
||||
* @method Phaser.GameObjects.GameObjectFactory#spine
|
||||
* @since 3.16.0
|
||||
*
|
||||
* @param {number} x - The horizontal position of this Game Object.
|
||||
* @param {number} y - The vertical position of this Game Object.
|
||||
* @param {string} texture - The key 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.SpineGameObject} The Game Object that was created.
|
||||
*/
|
||||
GameObjectFactory.register('spine', function (x, y, key, animation)
|
||||
{
|
||||
var spine = new SpineGameObject(this.scene, x, y, key, animation);
|
||||
|
||||
this.displayList.add(spine);
|
||||
this.updateList.add(spine);
|
||||
|
||||
return spine;
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,51 +1,65 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
var CounterClockwise = require('../../../../src/math/angle/CounterClockwise');
|
||||
var RadToDeg = require('../../../../src/math/RadToDeg');
|
||||
var Wrap = require('../../../../src/math/Wrap');
|
||||
|
||||
/**
|
||||
* Renders this Game Object with the Canvas Renderer to the given Camera.
|
||||
* Renders this Game Object with the WebGL Renderer to the given Camera.
|
||||
* The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
|
||||
* This method should not be called directly. It is a utility function of the Render module.
|
||||
*
|
||||
* @method Phaser.GameObjects.SpineGameObject#renderCanvas
|
||||
* @since 3.16.0
|
||||
* @method SpineGameObject#renderWebGL
|
||||
* @since 3.19.0
|
||||
* @private
|
||||
*
|
||||
* @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer.
|
||||
* @param {Phaser.GameObjects.SpineGameObject} src - The Game Object being rendered in this call.
|
||||
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
|
||||
* @param {SpineGameObject} src - The Game Object being rendered in this call.
|
||||
* @param {number} interpolationPercentage - Reserved for future use and custom pipelines.
|
||||
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
|
||||
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
|
||||
*/
|
||||
var SpineGameObjectWebGLRenderer = function (renderer, src, interpolationPercentage, camera, parentMatrix)
|
||||
{
|
||||
var pipeline = renderer.currentPipeline;
|
||||
var plugin = src.plugin;
|
||||
var mvp = plugin.mvp;
|
||||
|
||||
var shader = plugin.shader;
|
||||
var batcher = plugin.batcher;
|
||||
var runtime = src.runtime;
|
||||
var skeleton = src.skeleton;
|
||||
var skeletonRenderer = plugin.skeletonRenderer;
|
||||
var sceneRenderer = plugin.sceneRenderer;
|
||||
|
||||
if (!skeleton)
|
||||
var GameObjectRenderMask = 15;
|
||||
|
||||
var willRender = !(GameObjectRenderMask !== src.renderFlags || (src.cameraFilter !== 0 && (src.cameraFilter & camera.id)));
|
||||
|
||||
if (!skeleton || !willRender)
|
||||
{
|
||||
// Reset the current type
|
||||
renderer.currentType = '';
|
||||
|
||||
// If there is already a batch running, we need to close it
|
||||
if (!renderer.nextTypeMatch)
|
||||
{
|
||||
// The next object in the display list is not a Spine object, so we end the batch
|
||||
sceneRenderer.end();
|
||||
|
||||
renderer.rebindPipeline(renderer.pipelines.TextureTintPipeline);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
renderer.clearPipeline();
|
||||
if (renderer.newType)
|
||||
{
|
||||
renderer.clearPipeline();
|
||||
}
|
||||
|
||||
var camMatrix = renderer._tempMatrix1;
|
||||
var spriteMatrix = renderer._tempMatrix2;
|
||||
var calcMatrix = renderer._tempMatrix3;
|
||||
|
||||
// - 90 degrees to account for the difference in Spine vs. Phaser rotation
|
||||
spriteMatrix.applyITRS(src.x, src.y, src.rotation - 1.5707963267948966, src.scaleX, src.scaleY);
|
||||
spriteMatrix.applyITRS(src.x, src.y, src.rotation, Math.abs(src.scaleX), Math.abs(src.scaleY));
|
||||
|
||||
camMatrix.copyFrom(camera.matrix);
|
||||
|
||||
|
@ -70,52 +84,79 @@ var SpineGameObjectWebGLRenderer = function (renderer, src, interpolationPercent
|
|||
camMatrix.multiply(spriteMatrix, calcMatrix);
|
||||
}
|
||||
|
||||
var width = renderer.width;
|
||||
var height = renderer.height;
|
||||
var viewportHeight = renderer.height;
|
||||
|
||||
var data = calcMatrix.decomposeMatrix();
|
||||
skeleton.x = calcMatrix.tx;
|
||||
skeleton.y = viewportHeight - calcMatrix.ty;
|
||||
|
||||
mvp.ortho(0, width, 0, height, 0, 1);
|
||||
mvp.translateXYZ(data.translateX, height - data.translateY, 0);
|
||||
mvp.rotateZ(CounterClockwise(data.rotation));
|
||||
mvp.scaleXYZ(data.scaleX, data.scaleY, 1);
|
||||
skeleton.scaleX = calcMatrix.scaleX;
|
||||
skeleton.scaleY = calcMatrix.scaleY;
|
||||
|
||||
// For a Stage 1 release we'll handle it like this:
|
||||
shader.bind();
|
||||
shader.setUniformi(runtime.webgl.Shader.SAMPLER, 0);
|
||||
shader.setUniform4x4f(runtime.webgl.Shader.MVP_MATRIX, mvp.val);
|
||||
if (src.scaleX < 0)
|
||||
{
|
||||
skeleton.scaleX *= -1;
|
||||
|
||||
// For Stage 2, we'll move to using a custom pipeline, so Spine objects are batched
|
||||
src.root.rotation = RadToDeg(calcMatrix.rotationNormalized);
|
||||
}
|
||||
else
|
||||
{
|
||||
// +90 degrees to account for the difference in Spine vs. Phaser rotation
|
||||
src.root.rotation = Wrap(RadToDeg(CounterClockwise(calcMatrix.rotationNormalized)) + 90, 0, 360);
|
||||
}
|
||||
|
||||
batcher.begin(shader);
|
||||
if (src.scaleY < 0)
|
||||
{
|
||||
skeleton.scaleY *= -1;
|
||||
|
||||
skeletonRenderer.premultipliedAlpha = true;
|
||||
if (src.scaleX < 0)
|
||||
{
|
||||
src.root.rotation -= (RadToDeg(calcMatrix.rotationNormalized) * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
src.root.rotation += (RadToDeg(calcMatrix.rotationNormalized) * 2);
|
||||
}
|
||||
}
|
||||
|
||||
skeletonRenderer.draw(batcher, skeleton);
|
||||
if (camera.renderToTexture)
|
||||
{
|
||||
skeleton.y = calcMatrix.ty;
|
||||
skeleton.scaleY *= -1;
|
||||
}
|
||||
|
||||
batcher.end();
|
||||
// Add autoUpdate option
|
||||
skeleton.updateWorldTransform();
|
||||
|
||||
shader.unbind();
|
||||
if (renderer.newType)
|
||||
{
|
||||
sceneRenderer.begin();
|
||||
}
|
||||
|
||||
// Draw the current skeleton
|
||||
sceneRenderer.drawSkeleton(skeleton, src.preMultipliedAlpha);
|
||||
|
||||
if (plugin.drawDebug || src.drawDebug)
|
||||
{
|
||||
var debugShader = plugin.debugShader;
|
||||
var debugRenderer = plugin.debugRenderer;
|
||||
var shapes = plugin.shapes;
|
||||
// Because if we don't, the bones render positions are completely wrong (*sigh*)
|
||||
var oldX = skeleton.x;
|
||||
var oldY = skeleton.y;
|
||||
|
||||
debugShader.bind();
|
||||
debugShader.setUniform4x4f(runtime.webgl.Shader.MVP_MATRIX, mvp.val);
|
||||
skeleton.x = 0;
|
||||
skeleton.y = 0;
|
||||
|
||||
shapes.begin(debugShader);
|
||||
sceneRenderer.drawSkeletonDebug(skeleton, src.preMultipliedAlpha);
|
||||
|
||||
debugRenderer.draw(shapes, skeleton);
|
||||
|
||||
shapes.end();
|
||||
|
||||
debugShader.unbind();
|
||||
skeleton.x = oldX;
|
||||
skeleton.y = oldY;
|
||||
}
|
||||
|
||||
renderer.rebindPipeline(pipeline);
|
||||
if (!renderer.nextTypeMatch)
|
||||
{
|
||||
// The next object in the display list is not a Spine object, so we end the batch
|
||||
sceneRenderer.end();
|
||||
|
||||
renderer.rebindPipeline(renderer.pipelines.TextureTintPipeline);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = SpineGameObjectWebGLRenderer;
|
||||
|
|
10725
plugins/spine/src/runtimes/spine-both.js
Normal file
10725
plugins/spine/src/runtimes/spine-both.js
Normal file
File diff suppressed because it is too large
Load diff
1
plugins/spine/src/runtimes/spine-both.js.map
Normal file
1
plugins/spine/src/runtimes/spine-both.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
1
plugins/spine/src/runtimes/spine-canvas.js.map
Normal file
1
plugins/spine/src/runtimes/spine-canvas.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
1
plugins/spine/src/runtimes/spine-webgl.js.map
Normal file
1
plugins/spine/src/runtimes/spine-webgl.js.map
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,8 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
const webpack = require('webpack');
|
||||
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||
const exec = require('child_process').exec;
|
||||
const RemovePlugin = require('remove-files-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
|
@ -10,14 +10,14 @@ module.exports = {
|
|||
context: `${__dirname}/src/`,
|
||||
|
||||
entry: {
|
||||
'SpinePlugin': './SpinePlugin.js'
|
||||
'SpinePluginDebug': './SpinePlugin.js'
|
||||
},
|
||||
|
||||
output: {
|
||||
path: `${__dirname}/dist/`,
|
||||
filename: '[name].js',
|
||||
library: 'SpinePlugin',
|
||||
libraryTarget: 'umd',
|
||||
libraryTarget: 'window',
|
||||
sourceMapFilename: '[file].map',
|
||||
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]', // string
|
||||
devtoolFallbackModuleFilenameTemplate: 'webpack:///[resource-path]?[hash]', // string
|
||||
|
@ -29,19 +29,11 @@ module.exports = {
|
|||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-canvas.js'),
|
||||
test: require.resolve('./src/runtimes/spine-both.js'),
|
||||
use: 'imports-loader?this=>window'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-canvas.js'),
|
||||
use: 'exports-loader?spine'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-webgl.js'),
|
||||
use: 'imports-loader?this=>window'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-webgl.js'),
|
||||
test: require.resolve('./src/runtimes/spine-both.js'),
|
||||
use: 'exports-loader?spine'
|
||||
}
|
||||
]
|
||||
|
@ -49,9 +41,8 @@ module.exports = {
|
|||
|
||||
resolve: {
|
||||
alias: {
|
||||
'SpineCanvas': './runtimes/spine-canvas.js',
|
||||
'SpineWebGL': './runtimes/spine-webgl.js'
|
||||
},
|
||||
'Spine': './runtimes/spine-both.js'
|
||||
}
|
||||
},
|
||||
|
||||
plugins: [
|
||||
|
@ -59,7 +50,12 @@ module.exports = {
|
|||
"typeof CANVAS_RENDERER": JSON.stringify(true),
|
||||
"typeof WEBGL_RENDERER": JSON.stringify(true)
|
||||
}),
|
||||
new CleanWebpackPlugin([ 'dist' ]),
|
||||
new RemovePlugin({
|
||||
before: {
|
||||
root: './plugins/spine/dist/',
|
||||
include: [ 'SpinePluginDebug.js', 'SpinePluginDebug.js.map' ]
|
||||
}
|
||||
}),
|
||||
{
|
||||
apply: (compiler) => {
|
||||
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
const webpack = require('webpack');
|
||||
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
|
||||
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||
const exec = require('child_process').exec;
|
||||
const RemovePlugin = require('remove-files-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
|
@ -11,19 +11,15 @@ module.exports = {
|
|||
context: `${__dirname}/src/`,
|
||||
|
||||
entry: {
|
||||
'SpinePlugin': './SpineWebGLPlugin.js',
|
||||
'SpinePlugin.min': './SpineWebGLPlugin.js'
|
||||
'SpinePlugin': './SpinePlugin.js',
|
||||
'SpinePlugin.min': './SpinePlugin.js'
|
||||
},
|
||||
|
||||
output: {
|
||||
path: `${__dirname}/dist/`,
|
||||
filename: '[name].js',
|
||||
library: 'SpinePlugin',
|
||||
libraryTarget: 'umd',
|
||||
sourceMapFilename: '[file].map',
|
||||
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]', // string
|
||||
devtoolFallbackModuleFilenameTemplate: 'webpack:///[resource-path]?[hash]', // string
|
||||
umdNamedDefine: true
|
||||
libraryTarget: 'window'
|
||||
},
|
||||
|
||||
performance: { hints: false },
|
||||
|
@ -31,19 +27,11 @@ module.exports = {
|
|||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-canvas.js'),
|
||||
test: require.resolve('./src/runtimes/spine-both.js'),
|
||||
use: 'imports-loader?this=>window'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-canvas.js'),
|
||||
use: 'exports-loader?spine'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-webgl.js'),
|
||||
use: 'imports-loader?this=>window'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-webgl.js'),
|
||||
test: require.resolve('./src/runtimes/spine-both.js'),
|
||||
use: 'exports-loader?spine'
|
||||
}
|
||||
]
|
||||
|
@ -51,8 +39,7 @@ module.exports = {
|
|||
|
||||
resolve: {
|
||||
alias: {
|
||||
'SpineCanvas': './runtimes/spine-canvas.js',
|
||||
'SpineWebGL': './runtimes/spine-webgl.js'
|
||||
'Spine': './runtimes/spine-both.js'
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -79,7 +66,12 @@ module.exports = {
|
|||
"typeof CANVAS_RENDERER": JSON.stringify(true),
|
||||
"typeof WEBGL_RENDERER": JSON.stringify(true)
|
||||
}),
|
||||
new CleanWebpackPlugin([ 'dist' ]),
|
||||
new RemovePlugin({
|
||||
before: {
|
||||
root: './plugins/spine/dist/',
|
||||
include: [ 'SpinePlugin.js', 'SpinePlugin.min.js' ]
|
||||
}
|
||||
}),
|
||||
{
|
||||
apply: (compiler) => {
|
||||
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
const webpack = require('webpack');
|
||||
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||
const exec = require('child_process').exec;
|
||||
const RemovePlugin = require('remove-files-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
|
@ -10,14 +10,14 @@ module.exports = {
|
|||
context: `${__dirname}/src/`,
|
||||
|
||||
entry: {
|
||||
'SpineCanvasPlugin': './SpineCanvasPlugin.js'
|
||||
'SpineCanvasPluginDebug': './SpinePlugin.js'
|
||||
},
|
||||
|
||||
output: {
|
||||
path: `${__dirname}/dist/`,
|
||||
filename: '[name].js',
|
||||
library: 'SpineCanvasPlugin',
|
||||
libraryTarget: 'umd',
|
||||
library: 'SpinePlugin',
|
||||
libraryTarget: 'window',
|
||||
sourceMapFilename: '[file].map',
|
||||
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]', // string
|
||||
devtoolFallbackModuleFilenameTemplate: 'webpack:///[resource-path]?[hash]', // string
|
||||
|
@ -35,23 +35,14 @@ module.exports = {
|
|||
{
|
||||
test: require.resolve('./src/runtimes/spine-canvas.js'),
|
||||
use: 'exports-loader?spine'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-webgl.js'),
|
||||
use: 'imports-loader?this=>window'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-webgl.js'),
|
||||
use: 'exports-loader?spine'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
resolve: {
|
||||
alias: {
|
||||
'SpineCanvas': './runtimes/spine-canvas.js',
|
||||
'SpineWebGL': './runtimes/spine-webgl.js'
|
||||
},
|
||||
'Spine': './runtimes/spine-canvas.js'
|
||||
}
|
||||
},
|
||||
|
||||
plugins: [
|
||||
|
@ -59,7 +50,14 @@ module.exports = {
|
|||
"typeof CANVAS_RENDERER": JSON.stringify(true),
|
||||
"typeof WEBGL_RENDERER": JSON.stringify(false)
|
||||
}),
|
||||
new CleanWebpackPlugin([ 'dist' ]),
|
||||
new RemovePlugin({
|
||||
before: {
|
||||
before: {
|
||||
root: './plugins/spine/dist/',
|
||||
include: [ 'SpineCanvasPluginDebug.js', 'SpineCanvasPluginDebug.js.map' ]
|
||||
}
|
||||
}
|
||||
}),
|
||||
{
|
||||
apply: (compiler) => {
|
||||
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
const webpack = require('webpack');
|
||||
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
|
||||
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||
const exec = require('child_process').exec;
|
||||
const RemovePlugin = require('remove-files-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
|
@ -11,19 +11,15 @@ module.exports = {
|
|||
context: `${__dirname}/src/`,
|
||||
|
||||
entry: {
|
||||
'SpineCanvasPlugin': './SpineCanvasPlugin.js',
|
||||
'SpineCanvasPlugin.min': './SpineCanvasPlugin.js'
|
||||
'SpineCanvasPlugin': './SpinePlugin.js',
|
||||
'SpineCanvasPlugin.min': './SpinePlugin.js'
|
||||
},
|
||||
|
||||
output: {
|
||||
path: `${__dirname}/dist/`,
|
||||
filename: '[name].js',
|
||||
library: 'SpineCanvasPlugin',
|
||||
libraryTarget: 'umd',
|
||||
sourceMapFilename: '[file].map',
|
||||
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]', // string
|
||||
devtoolFallbackModuleFilenameTemplate: 'webpack:///[resource-path]?[hash]', // string
|
||||
umdNamedDefine: true
|
||||
library: 'SpinePlugin',
|
||||
libraryTarget: 'window'
|
||||
},
|
||||
|
||||
performance: { hints: false },
|
||||
|
@ -37,23 +33,14 @@ module.exports = {
|
|||
{
|
||||
test: require.resolve('./src/runtimes/spine-canvas.js'),
|
||||
use: 'exports-loader?spine'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-webgl.js'),
|
||||
use: 'imports-loader?this=>window'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-webgl.js'),
|
||||
use: 'exports-loader?spine'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
resolve: {
|
||||
alias: {
|
||||
'SpineCanvas': './runtimes/spine-canvas.js',
|
||||
'SpineWebGL': './runtimes/spine-webgl.js'
|
||||
},
|
||||
'Spine': './runtimes/spine-canvas.js'
|
||||
}
|
||||
},
|
||||
|
||||
optimization: {
|
||||
|
@ -79,7 +66,14 @@ module.exports = {
|
|||
"typeof CANVAS_RENDERER": JSON.stringify(true),
|
||||
"typeof WEBGL_RENDERER": JSON.stringify(false)
|
||||
}),
|
||||
new CleanWebpackPlugin([ 'dist' ]),
|
||||
new RemovePlugin({
|
||||
before: {
|
||||
before: {
|
||||
root: './plugins/spine/dist/',
|
||||
include: [ 'SpineCanvasPlugin.js', 'SpineCanvasPlugin.min.js' ]
|
||||
}
|
||||
}
|
||||
}),
|
||||
{
|
||||
apply: (compiler) => {
|
||||
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
const webpack = require('webpack');
|
||||
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||
const exec = require('child_process').exec;
|
||||
const RemovePlugin = require('remove-files-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
|
@ -10,14 +10,14 @@ module.exports = {
|
|||
context: `${__dirname}/src/`,
|
||||
|
||||
entry: {
|
||||
'SpineWebGLPlugin': './SpineWebGLPlugin.js'
|
||||
'SpineWebGLPluginDebug': './SpinePlugin.js'
|
||||
},
|
||||
|
||||
output: {
|
||||
path: `${__dirname}/dist/`,
|
||||
filename: '[name].js',
|
||||
library: 'SpineWebGLPlugin',
|
||||
libraryTarget: 'umd',
|
||||
library: 'SpinePlugin',
|
||||
libraryTarget: 'window',
|
||||
sourceMapFilename: '[file].map',
|
||||
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]', // string
|
||||
devtoolFallbackModuleFilenameTemplate: 'webpack:///[resource-path]?[hash]', // string
|
||||
|
@ -28,14 +28,6 @@ module.exports = {
|
|||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-canvas.js'),
|
||||
use: 'imports-loader?this=>window'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-canvas.js'),
|
||||
use: 'exports-loader?spine'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-webgl.js'),
|
||||
use: 'imports-loader?this=>window'
|
||||
|
@ -49,8 +41,7 @@ module.exports = {
|
|||
|
||||
resolve: {
|
||||
alias: {
|
||||
'SpineCanvas': './runtimes/spine-canvas.js',
|
||||
'SpineWebGL': './runtimes/spine-webgl.js'
|
||||
'Spine': './runtimes/spine-webgl.js'
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -59,7 +50,14 @@ module.exports = {
|
|||
"typeof CANVAS_RENDERER": JSON.stringify(false),
|
||||
"typeof WEBGL_RENDERER": JSON.stringify(true)
|
||||
}),
|
||||
new CleanWebpackPlugin([ 'dist' ]),
|
||||
new RemovePlugin({
|
||||
before: {
|
||||
before: {
|
||||
root: './plugins/spine/dist/',
|
||||
include: [ 'SpineWebGLPluginDebug.js', 'SpineWebGLPluginDebug.js.map' ]
|
||||
}
|
||||
}
|
||||
}),
|
||||
{
|
||||
apply: (compiler) => {
|
||||
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
const webpack = require('webpack');
|
||||
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
|
||||
const CleanWebpackPlugin = require('clean-webpack-plugin');
|
||||
const exec = require('child_process').exec;
|
||||
const RemovePlugin = require('remove-files-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
|
@ -11,33 +11,21 @@ module.exports = {
|
|||
context: `${__dirname}/src/`,
|
||||
|
||||
entry: {
|
||||
'SpineWebGLPlugin': './SpineWebGLPlugin.js',
|
||||
'SpineWebGLPlugin.min': './SpineWebGLPlugin.js'
|
||||
'SpineWebGLPlugin': './SpinePlugin.js',
|
||||
'SpineWebGLPlugin.min': './SpinePlugin.js'
|
||||
},
|
||||
|
||||
output: {
|
||||
path: `${__dirname}/dist/`,
|
||||
filename: '[name].js',
|
||||
library: 'SpineWebGLPlugin',
|
||||
libraryTarget: 'umd',
|
||||
sourceMapFilename: '[file].map',
|
||||
devtoolModuleFilenameTemplate: 'webpack:///[resource-path]', // string
|
||||
devtoolFallbackModuleFilenameTemplate: 'webpack:///[resource-path]?[hash]', // string
|
||||
umdNamedDefine: true
|
||||
library: 'SpinePlugin',
|
||||
libraryTarget: 'window'
|
||||
},
|
||||
|
||||
performance: { hints: false },
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-canvas.js'),
|
||||
use: 'imports-loader?this=>window'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-canvas.js'),
|
||||
use: 'exports-loader?spine'
|
||||
},
|
||||
{
|
||||
test: require.resolve('./src/runtimes/spine-webgl.js'),
|
||||
use: 'imports-loader?this=>window'
|
||||
|
@ -51,9 +39,8 @@ module.exports = {
|
|||
|
||||
resolve: {
|
||||
alias: {
|
||||
'SpineCanvas': './runtimes/spine-canvas.js',
|
||||
'SpineWebGL': './runtimes/spine-webgl.js'
|
||||
},
|
||||
'Spine': './runtimes/spine-webgl.js'
|
||||
}
|
||||
},
|
||||
|
||||
optimization: {
|
||||
|
@ -79,7 +66,14 @@ module.exports = {
|
|||
"typeof CANVAS_RENDERER": JSON.stringify(false),
|
||||
"typeof WEBGL_RENDERER": JSON.stringify(true)
|
||||
}),
|
||||
new CleanWebpackPlugin([ 'dist' ]),
|
||||
new RemovePlugin({
|
||||
before: {
|
||||
before: {
|
||||
root: './plugins/spine/dist/',
|
||||
include: [ 'SpineWebGLPlugin.js', 'SpineWebGLPlugin.min.js' ]
|
||||
}
|
||||
}
|
||||
}),
|
||||
{
|
||||
apply: (compiler) => {
|
||||
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
|
||||
|
|
|
@ -6,20 +6,28 @@ v.log('{bgYellow}{black} | ___/ | \\\\__ \\ / ___// __ \\_ __ \\ _(
|
|||
v.log('{bgYellow}{black} | | | Y \\/ __ \\_\\___ \\\\ ___/| | \\/ / \\ ');
|
||||
v.log('{bgYellow}{black} |____| |___| (____ /____ >\\___ >__| /______ / ');
|
||||
v.log('{bgYellow}{black} \\/ \\/ \\/ \\/ \\/ ');
|
||||
v.log('{bgYellow}{black} Available commands: ');
|
||||
v.log('{bgYellow}{black} Available commands: ');
|
||||
|
||||
v.log('{white}* npm run {green}build {cyan} Build dev version of Phaser with Webpack');
|
||||
v.log('{white}* npm run {green}watch {cyan} Build dev & put Webpack in watch mode');
|
||||
v.log('{white}* npm run {green}dist {cyan} Build dist versions of Phaser');
|
||||
v.log('{white}* npm run {green}lint {cyan} ESLint check Phaser source');
|
||||
v.log('{white}* npm run {green}lintfix {cyan} ESLint check and fix Phaser source');
|
||||
v.log('{white}* npm run {green}sloc {cyan} Get source code & comments line count');
|
||||
v.log('{white}* npm run {green}bundleshaders {cyan} Convert vert/frag shaders to js');
|
||||
v.log('{white}* npm run {green}plugin.cam3d {cyan} Build Camera3D Plugin');
|
||||
v.log('{white}Facebook Instant Games:');
|
||||
v.log('{white}* npm run {green}buildfb {cyan} Build dev Phaser FB with Webpack');
|
||||
v.log('{white}* npm run {green}watchfb {cyan} Build FB dev in Webpack watch mode');
|
||||
v.log('{white}* npm run {green}distfb {cyan} Build dist versions of Phaser FB');
|
||||
v.log('{white}* npm run {green}distfull {cyan} Build dist versions of Phaser + FB');
|
||||
v.log('{white} npm run {green}build {cyan} Build dev version of Phaser with Webpack');
|
||||
v.log('{white} npm run {green}watch {cyan} Build dev & put Webpack in watch mode');
|
||||
v.log('{white} npm run {green}dist {cyan} Build dist versions of Phaser');
|
||||
v.log('{white} npm run {green}lint {cyan} ESLint check Phaser source');
|
||||
v.log('{white} npm run {green}lintfix {cyan} ESLint check and fix Phaser source');
|
||||
v.log('{white} npm run {green}sloc {cyan} Get source code & comments line count');
|
||||
v.log('{white} npm run {green}bundleshaders {cyan} Convert vert/frag shaders to js');
|
||||
v.log('{white} npm run {green}plugin.cam3d {cyan} Build Camera3D Plugin');
|
||||
v.log('');
|
||||
v.log(' {white}{bold}Facebook Instant Games{/bold}');
|
||||
v.log('');
|
||||
v.log('{white} npm run {green}buildfb {cyan} Build dev Phaser FB with Webpack');
|
||||
v.log('{white} npm run {green}watchfb {cyan} Build FB dev in Webpack watch mode');
|
||||
v.log('{white} npm run {green}distfb {cyan} Build dist versions of Phaser FB');
|
||||
v.log('{white} npm run {green}distfull {cyan} Build dist versions of Phaser + FB');
|
||||
v.log('');
|
||||
v.log(' {white}{bold}TypeScript{/bold}');
|
||||
v.log('');
|
||||
v.log('{white} npm run {green}build-tsgen {cyan} Build the TypeScript Defs parser');
|
||||
v.log('{white} npm run {green}tsgen {cyan} Generate the TypeScript Defs');
|
||||
v.log('{white} npm run {green}test-ts {cyan} Test the TypeScript Defs');
|
||||
|
||||
v.log('{bgYellow}{black} https://phaser.io https://labs.phaser.io ');
|
||||
v.log('{bgYellow}{black} https://phaser.io https://labs.phaser.io ');
|
||||
|
|
7
scripts/tsgen/README.md
Normal file
7
scripts/tsgen/README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
## TypeScript Defs Generation Tool
|
||||
|
||||
The TypeScript defs generation tool is called `tsgen` and is written in TypeScript. Build it by running `npm run build-tsgen`. This will compile the parser locally.
|
||||
|
||||
You can then run `npm run tsgen` to build the actual defs. They will replace the file located in the root `types` folder. Once the parser is built you only need use this command. Use it to re-generate the defs if you have modified the Phaser source code and wish to test your change worked.
|
||||
|
||||
There is also a test script available: `npm run test-ts` which will compile a test TypeScript project and output any compilation errors to `output.txt`.
|
503
scripts/tsgen/bin/Parser.js
Normal file
503
scripts/tsgen/bin/Parser.js
Normal file
|
@ -0,0 +1,503 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const dom = require("dts-dom");
|
||||
const regexEndLine = /^(.*)\r\n|\n|\r/gm;
|
||||
class Parser {
|
||||
constructor(docs) {
|
||||
this.topLevel = [];
|
||||
this.objects = {};
|
||||
this.namespaces = {};
|
||||
// parse doclets and create corresponding dom objects
|
||||
this.parseObjects(docs);
|
||||
this.resolveObjects(docs);
|
||||
// removes members inherited from classes
|
||||
// possibly could be avoided if mixins were defined as such before JSDoc parses them and then we could globally remove all inherited (not
|
||||
// overriden) members globally from the parsed DB
|
||||
this.resolveInheritance(docs);
|
||||
this.resolveParents(docs);
|
||||
// add integer alias
|
||||
this.topLevel.push(dom.create.alias('integer', dom.type.number));
|
||||
// add declare module
|
||||
const phaserPkgModuleDOM = dom.create.module('phaser');
|
||||
phaserPkgModuleDOM.members.push(dom.create.exportEquals('Phaser'));
|
||||
this.topLevel.push(phaserPkgModuleDOM);
|
||||
}
|
||||
emit() {
|
||||
let ignored = [];
|
||||
let result = this.topLevel.reduce((out, obj) => {
|
||||
// TODO: remove once stable
|
||||
// if (<string>obj.kind === 'property') {
|
||||
// ignored.push((<any>obj).name);
|
||||
// return out;
|
||||
// }
|
||||
//////////////////////////
|
||||
return out + dom.emit(obj);
|
||||
}, '');
|
||||
if (ignored.length > 0) {
|
||||
console.log('ignored top level properties:');
|
||||
console.log(ignored);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
parseObjects(docs) {
|
||||
for (let i = 0; i < docs.length; i++) {
|
||||
let doclet = docs[i];
|
||||
// TODO: Custom temporary rules
|
||||
switch (doclet.longname) {
|
||||
case 'Phaser.GameObjects.Components.Alpha':
|
||||
case 'Phaser.GameObjects.Components.Animation':
|
||||
case 'Phaser.GameObjects.Components.BlendMode':
|
||||
case 'Phaser.GameObjects.Components.ComputedSize':
|
||||
case 'Phaser.GameObjects.Components.Crop':
|
||||
case 'Phaser.GameObjects.Components.Depth':
|
||||
case 'Phaser.GameObjects.Components.Flip':
|
||||
case 'Phaser.GameObjects.Components.GetBounds':
|
||||
case 'Phaser.GameObjects.Components.Mask':
|
||||
case 'Phaser.GameObjects.Components.Origin':
|
||||
case 'Phaser.GameObjects.Components.PathFollower':
|
||||
case 'Phaser.GameObjects.Components.Pipeline':
|
||||
case 'Phaser.GameObjects.Components.ScrollFactor':
|
||||
case 'Phaser.GameObjects.Components.Size':
|
||||
case 'Phaser.GameObjects.Components.Texture':
|
||||
case 'Phaser.GameObjects.Components.TextureCrop':
|
||||
case 'Phaser.GameObjects.Components.Tint':
|
||||
case 'Phaser.GameObjects.Components.ToJSON':
|
||||
case 'Phaser.GameObjects.Components.Transform':
|
||||
case 'Phaser.GameObjects.Components.Visible':
|
||||
case 'Phaser.Renderer.WebGL.Pipelines.ModelViewProjection':
|
||||
doclet.kind = 'mixin';
|
||||
break;
|
||||
// Because, sod you TypeScript
|
||||
case 'Phaser.BlendModes':
|
||||
case 'Phaser.ScaleModes':
|
||||
case 'Phaser.Physics.Impact.TYPE':
|
||||
case 'Phaser.Physics.Impact.COLLIDES':
|
||||
case 'Phaser.Scale.Center':
|
||||
case 'Phaser.Scale.Orientation':
|
||||
case 'Phaser.Scale.ScaleModes':
|
||||
case 'Phaser.Scale.Zoom':
|
||||
case 'Phaser.Textures.FilterMode':
|
||||
// console.log('Forcing enum for ' + doclet.longname);
|
||||
doclet.kind = 'member';
|
||||
doclet.isEnum = true;
|
||||
break;
|
||||
}
|
||||
if ((doclet.longname.indexOf('Phaser.Physics.Arcade.Components.') == 0 || doclet.longname.indexOf('Phaser.Physics.Impact.Components.') == 0 || doclet.longname.indexOf('Phaser.Physics.Matter.Components.') == 0) && doclet.longname.indexOf('#') == -1) {
|
||||
doclet.kind = 'mixin';
|
||||
}
|
||||
let obj;
|
||||
let container = this.objects;
|
||||
switch (doclet.kind) {
|
||||
case 'namespace':
|
||||
obj = this.createNamespace(doclet);
|
||||
container = this.namespaces;
|
||||
break;
|
||||
case 'class':
|
||||
obj = this.createClass(doclet);
|
||||
break;
|
||||
case 'mixin':
|
||||
obj = this.createInterface(doclet);
|
||||
break;
|
||||
case 'member':
|
||||
if (doclet.isEnum === true) {
|
||||
obj = this.createEnum(doclet);
|
||||
break;
|
||||
}
|
||||
case 'constant':
|
||||
obj = this.createMember(doclet);
|
||||
break;
|
||||
case 'function':
|
||||
obj = this.createFunction(doclet);
|
||||
break;
|
||||
case 'typedef':
|
||||
obj = this.createTypedef(doclet);
|
||||
break;
|
||||
case 'event':
|
||||
obj = this.createEvent(doclet);
|
||||
break;
|
||||
default:
|
||||
console.log('Ignored doclet kind: ' + doclet.kind);
|
||||
break;
|
||||
}
|
||||
if (obj) {
|
||||
if (container[doclet.longname]) {
|
||||
console.log('Warning: ignoring duplicate doc name: ' + doclet.longname);
|
||||
docs.splice(i--, 1);
|
||||
continue;
|
||||
}
|
||||
container[doclet.longname] = obj;
|
||||
if (doclet.description) {
|
||||
let otherDocs = obj.jsDocComment || '';
|
||||
obj.jsDocComment = doclet.description.replace(regexEndLine, '$1\n') + otherDocs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resolveObjects(docs) {
|
||||
let allTypes = new Set();
|
||||
for (let doclet of docs) {
|
||||
let obj = doclet.kind === 'namespace' ? this.namespaces[doclet.longname] : this.objects[doclet.longname];
|
||||
if (!obj) {
|
||||
// TODO
|
||||
console.log(`Warning: Didn't find object for ${doclet.longname}`);
|
||||
continue;
|
||||
}
|
||||
if (!doclet.memberof) {
|
||||
this.topLevel.push(obj);
|
||||
}
|
||||
else {
|
||||
let isNamespaceMember = doclet.kind === 'class' || doclet.kind === 'typedef' || doclet.kind == 'namespace' || doclet.isEnum;
|
||||
let parent = isNamespaceMember ? this.namespaces[doclet.memberof] : (this.objects[doclet.memberof] || this.namespaces[doclet.memberof]);
|
||||
//TODO: this whole section should be removed once stable
|
||||
if (!parent) {
|
||||
console.log(`${doclet.longname} in ${doclet.meta.filename}@${doclet.meta.lineno} has parent '${doclet.memberof}' that is not defined.`);
|
||||
let parts = doclet.memberof.split('.');
|
||||
let newParts = [parts.pop()];
|
||||
while (parts.length > 0 && this.objects[parts.join('.')] == null)
|
||||
newParts.unshift(parts.pop());
|
||||
parent = this.objects[parts.join('.')];
|
||||
if (parent == null) {
|
||||
parent = dom.create.namespace(doclet.memberof);
|
||||
this.namespaces[doclet.memberof] = parent;
|
||||
this.topLevel.push(parent);
|
||||
}
|
||||
else {
|
||||
while (newParts.length > 0) {
|
||||
let oldParent = parent;
|
||||
parent = dom.create.namespace(newParts.shift());
|
||||
parts.push(parent.name);
|
||||
this.namespaces[parts.join('.')] = parent;
|
||||
oldParent.members.push(parent);
|
||||
parent._parent = oldParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////
|
||||
if (parent.members) {
|
||||
parent.members.push(obj);
|
||||
}
|
||||
else {
|
||||
console.log('Cannot find members array for:');
|
||||
console.log(parent);
|
||||
}
|
||||
obj._parent = parent;
|
||||
// class/interface members have methods, not functions
|
||||
if ((parent.kind === 'class' || parent.kind === 'interface')
|
||||
&& obj.kind === 'function')
|
||||
obj.kind = 'method';
|
||||
// namespace members are vars or consts, not properties
|
||||
if (parent.kind === 'namespace' && obj.kind === 'property') {
|
||||
if (doclet.kind == 'constant')
|
||||
obj.kind = 'const';
|
||||
else
|
||||
obj.kind = 'var';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resolveInheritance(docs) {
|
||||
for (let doclet of docs) {
|
||||
let obj = doclet.kind === 'namespace' ? this.namespaces[doclet.longname] : this.objects[doclet.longname];
|
||||
if (!obj) {
|
||||
// TODO
|
||||
console.log(`Didn't find type ${doclet.longname} ???`);
|
||||
continue;
|
||||
}
|
||||
if (!obj._parent)
|
||||
continue;
|
||||
if (doclet.inherited) { // remove inherited members if they aren't from an interface
|
||||
let from = this.objects[doclet.inherits];
|
||||
if (!from || !from._parent)
|
||||
throw `'${doclet.longname}' should inherit from '${doclet.inherits}', which is not defined.`;
|
||||
if (from._parent.kind != 'interface') {
|
||||
obj._parent.members.splice(obj._parent.members.indexOf(obj), 1);
|
||||
obj._parent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resolveParents(docs) {
|
||||
for (let doclet of docs) {
|
||||
let obj = this.objects[doclet.longname];
|
||||
if (!obj || doclet.kind !== 'class')
|
||||
continue;
|
||||
let o = obj;
|
||||
// resolve augments
|
||||
if (doclet.augments && doclet.augments.length) {
|
||||
for (let augment of doclet.augments) {
|
||||
let name = this.prepareTypeName(augment);
|
||||
let wrappingName = name.match(/[^<]+/s)[0]; //gets everything up to a first < (to handle augments with type parameters)
|
||||
let baseType = this.objects[wrappingName];
|
||||
if (!baseType) {
|
||||
console.log(`ERROR: Did not find base type: ${augment} for ${doclet.longname}`);
|
||||
}
|
||||
else {
|
||||
if (baseType.kind == 'class') {
|
||||
o.baseType = dom.create.class(name);
|
||||
}
|
||||
else {
|
||||
o.implements.push(dom.create.interface(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
createNamespace(doclet) {
|
||||
/**
|
||||
namespace: { comment: '',
|
||||
meta:
|
||||
{ filename: 'index.js',
|
||||
lineno: 10,
|
||||
columnno: 0,
|
||||
path: '/Users/rich/Documents/GitHub/phaser/src/tweens',
|
||||
code: {} },
|
||||
kind: 'namespace',
|
||||
name: 'Tweens',
|
||||
memberof: 'Phaser',
|
||||
longname: 'Phaser.Tweens',
|
||||
scope: 'static',
|
||||
___id: 'T000002R034468',
|
||||
___s: true }
|
||||
*/
|
||||
// console.log('namespace:', doclet.longname);
|
||||
let obj = dom.create.namespace(doclet.name);
|
||||
return obj;
|
||||
}
|
||||
createClass(doclet) {
|
||||
let obj = dom.create.class(doclet.name);
|
||||
let params = null;
|
||||
if (doclet.params) {
|
||||
let ctor = dom.create.constructor(null);
|
||||
this.setParams(doclet, ctor);
|
||||
params = ctor.parameters;
|
||||
obj.members.push(ctor);
|
||||
ctor._parent = obj;
|
||||
}
|
||||
this.processGeneric(doclet, obj, params);
|
||||
if (doclet.classdesc)
|
||||
doclet.description = doclet.classdesc.replace(regexEndLine, '$1\n'); // make sure docs will be added
|
||||
return obj;
|
||||
}
|
||||
createInterface(doclet) {
|
||||
return dom.create.interface(doclet.name);
|
||||
}
|
||||
createMember(doclet) {
|
||||
let type = this.parseType(doclet);
|
||||
let obj = dom.create.property(doclet.name, type);
|
||||
this.processGeneric(doclet, obj, null);
|
||||
this.processFlags(doclet, obj);
|
||||
return obj;
|
||||
}
|
||||
createEvent(doclet) {
|
||||
let type = this.parseType(doclet);
|
||||
let obj = dom.create.const(doclet.name, type);
|
||||
this.processFlags(doclet, obj);
|
||||
return obj;
|
||||
}
|
||||
createEnum(doclet) {
|
||||
let obj = dom.create.enum(doclet.name, false);
|
||||
this.processFlags(doclet, obj);
|
||||
return obj;
|
||||
}
|
||||
createFunction(doclet) {
|
||||
let returnType = dom.type.void;
|
||||
if (doclet.returns) {
|
||||
returnType = this.parseType(doclet.returns[0]);
|
||||
}
|
||||
let obj = dom.create.function(doclet.name, null, returnType);
|
||||
this.setParams(doclet, obj);
|
||||
this.processGeneric(doclet, obj, obj.parameters);
|
||||
this.processFlags(doclet, obj);
|
||||
return obj;
|
||||
}
|
||||
createTypedef(doclet) {
|
||||
const typeName = doclet.type.names[0];
|
||||
let type = null;
|
||||
if (doclet.type.names[0] === 'object') {
|
||||
let properties = [];
|
||||
for (let propDoc of doclet.properties) {
|
||||
let prop = this.createMember(propDoc);
|
||||
properties.push(prop);
|
||||
if (propDoc.description)
|
||||
prop.jsDocComment = propDoc.description.replace(regexEndLine, '$1\n');
|
||||
}
|
||||
type = dom.create.objectType(properties);
|
||||
if (doclet.augments && doclet.augments.length) {
|
||||
let intersectionTypes = [];
|
||||
for (let i = 0; i < doclet.augments.length; i++) {
|
||||
intersectionTypes.push(dom.create.namedTypeReference(doclet.augments[i]));
|
||||
}
|
||||
intersectionTypes.push(type);
|
||||
type = dom.create.intersection(intersectionTypes);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (doclet.type.names[0] == "function") {
|
||||
type = dom.create.functionType(null, dom.type.void);
|
||||
this.setParams(doclet, type);
|
||||
}
|
||||
else {
|
||||
type = this.parseType(doclet);
|
||||
}
|
||||
}
|
||||
let alias = dom.create.alias(doclet.name, type);
|
||||
this.processGeneric(doclet, alias, null);
|
||||
return alias;
|
||||
}
|
||||
setParams(doclet, obj) {
|
||||
let parameters = [];
|
||||
if (doclet.params) {
|
||||
let optional = false;
|
||||
obj.jsDocComment = '';
|
||||
for (let paramDoc of doclet.params) {
|
||||
// TODO REMOVE TEMP FIX
|
||||
if (paramDoc.name.indexOf('.') != -1) {
|
||||
console.log(`Warning: ignoring param with '.' for '${doclet.longname}' in ${doclet.meta.filename}@${doclet.meta.lineno}`);
|
||||
let defaultVal = paramDoc.defaultvalue !== undefined ? ` Default ${String(paramDoc.defaultvalue)}.` : '';
|
||||
if (paramDoc.description)
|
||||
obj.jsDocComment += `\n@param ${paramDoc.name} ${paramDoc.description.replace(regexEndLine, '$1\n')}` + defaultVal;
|
||||
else if (defaultVal.length)
|
||||
obj.jsDocComment += `\n@param ${paramDoc.name} ` + defaultVal;
|
||||
continue;
|
||||
}
|
||||
///////////////////////
|
||||
let param = dom.create.parameter(paramDoc.name, this.parseType(paramDoc));
|
||||
parameters.push(param);
|
||||
if (optional && paramDoc.optional != true) {
|
||||
console.log(`Warning: correcting to optional: parameter '${paramDoc.name}' for '${doclet.longname}' in ${doclet.meta.filename}@${doclet.meta.lineno}`);
|
||||
paramDoc.optional = true;
|
||||
}
|
||||
this.processFlags(paramDoc, param);
|
||||
optional = optional || paramDoc.optional === true;
|
||||
let defaultVal = paramDoc.defaultvalue !== undefined ? ` Default ${String(paramDoc.defaultvalue)}.` : '';
|
||||
if (paramDoc.description)
|
||||
obj.jsDocComment += `\n@param ${paramDoc.name} ${paramDoc.description.replace(regexEndLine, '$1\n')}` + defaultVal;
|
||||
else if (defaultVal.length)
|
||||
obj.jsDocComment += `\n@param ${paramDoc.name} ` + defaultVal;
|
||||
}
|
||||
}
|
||||
obj.parameters = parameters;
|
||||
}
|
||||
parseType(typeDoc) {
|
||||
if (!typeDoc || !typeDoc.type) {
|
||||
return dom.type.any;
|
||||
}
|
||||
else {
|
||||
let types = [];
|
||||
for (let name of typeDoc.type.names) {
|
||||
name = this.prepareTypeName(name);
|
||||
let type = dom.create.namedTypeReference(this.processTypeName(name));
|
||||
types.push(type);
|
||||
}
|
||||
if (types.length == 1)
|
||||
return types[0];
|
||||
else
|
||||
return dom.create.union(types);
|
||||
}
|
||||
}
|
||||
prepareTypeName(name) {
|
||||
if (name.indexOf('*') != -1) {
|
||||
name = name.split('*').join('any');
|
||||
}
|
||||
if (name.indexOf('.<') != -1 && name !== 'Array.<function()>') {
|
||||
name = name.split('.<').join('<');
|
||||
}
|
||||
return name;
|
||||
}
|
||||
processTypeName(name) {
|
||||
if (name === 'float')
|
||||
return 'number';
|
||||
if (name === 'function')
|
||||
return 'Function';
|
||||
if (name === 'Array.<function()>')
|
||||
return 'Function[]';
|
||||
if (name === 'array')
|
||||
return 'any[]';
|
||||
if (name.startsWith('Array<')) {
|
||||
let matches = name.match(/^Array<(.*)>$/);
|
||||
if (matches && matches[1]) {
|
||||
return this.processTypeName(matches[1]) + '[]';
|
||||
}
|
||||
}
|
||||
else if (name.startsWith('Object<')) {
|
||||
let matches = name.match(/^Object<(.*)>$/);
|
||||
if (matches && matches[1]) {
|
||||
if (matches[1].indexOf(',') != -1) {
|
||||
let parts = matches[1].split(',');
|
||||
return `{[key: ${this.processTypeName(parts[0])}]: ${this.processTypeName(parts[1])}}`;
|
||||
}
|
||||
else {
|
||||
return `{[key: string]: ${this.processTypeName(matches[1])}}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
processFlags(doclet, obj) {
|
||||
obj.flags = dom.DeclarationFlags.None;
|
||||
if (doclet.variable === true) {
|
||||
obj.flags |= dom.ParameterFlags.Rest;
|
||||
let type = obj.type;
|
||||
if (!type.name.endsWith('[]')) {
|
||||
if (type.name != 'any')
|
||||
console.log(`Warning: rest parameter should be an array type for ${doclet.longname}`);
|
||||
type.name = type.name + '[]'; // Must be an array
|
||||
}
|
||||
}
|
||||
else if (doclet.optional === true) { // Rest implies Optional – no need to flag it as such
|
||||
if (obj['kind'] === 'parameter')
|
||||
obj.flags |= dom.ParameterFlags.Optional;
|
||||
else
|
||||
obj.flags |= dom.DeclarationFlags.Optional;
|
||||
}
|
||||
switch (doclet.access) {
|
||||
case 'protected':
|
||||
obj.flags |= dom.DeclarationFlags.Protected;
|
||||
break;
|
||||
case 'private':
|
||||
obj.flags |= dom.DeclarationFlags.Private;
|
||||
break;
|
||||
}
|
||||
if (doclet.readonly || doclet.kind === 'constant')
|
||||
obj.flags |= dom.DeclarationFlags.ReadOnly;
|
||||
if (doclet.scope === 'static')
|
||||
obj.flags |= dom.DeclarationFlags.Static;
|
||||
}
|
||||
processGeneric(doclet, obj, params) {
|
||||
if (doclet.tags)
|
||||
for (let tag of doclet.tags) {
|
||||
if (tag.originalTitle === 'generic') {
|
||||
let matches = tag.value.match(/(?:(?:{)([^}]+)(?:}))?\s?([^\s]+)(?:\s?-\s?(?:\[)(.+)(?:\]))?/);
|
||||
let typeParam = dom.create.typeParameter(matches[2], matches[1] == null ? null : dom.create.typeParameter(matches[1]));
|
||||
obj.typeParameters.push(typeParam);
|
||||
handleOverrides(matches[3], matches[2]);
|
||||
}
|
||||
else if (tag.originalTitle === 'genericUse') {
|
||||
let matches = tag.value.match(/(?:(?:{)([^}]+)(?:}))(?:\s?-\s?(?:\[)(.+)(?:\]))?/);
|
||||
let overrideType = this.prepareTypeName(matches[1]);
|
||||
handleOverrides(matches[2], this.processTypeName(overrideType));
|
||||
}
|
||||
}
|
||||
function handleOverrides(matchedString, overrideType) {
|
||||
if (matchedString != null) {
|
||||
let overrides = matchedString.split(',');
|
||||
if (params != null) {
|
||||
for (let param of params) {
|
||||
if (overrides.indexOf(param.name) != -1) {
|
||||
param.type = dom.create.namedTypeReference(overrideType);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (overrides.indexOf('$return') != -1) { // has $return, must be a function
|
||||
obj.returnType = dom.create.namedTypeReference(overrideType);
|
||||
}
|
||||
if (overrides.indexOf('$type') != -1) { // has $type, must be a property
|
||||
obj.type = dom.create.namedTypeReference(overrideType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.Parser = Parser;
|
||||
//# sourceMappingURL=Parser.js.map
|
1
scripts/tsgen/bin/Parser.js.map
Normal file
1
scripts/tsgen/bin/Parser.js.map
Normal file
File diff suppressed because one or more lines are too long
25
scripts/tsgen/bin/publish.js
Normal file
25
scripts/tsgen/bin/publish.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
const Parser_1 = require("./Parser");
|
||||
function publish(data, opts) {
|
||||
// remove undocumented stuff.
|
||||
data({ undocumented: true }).remove();
|
||||
// remove package data
|
||||
data({ kind: 'package' }).remove();
|
||||
// remove header comments
|
||||
data({ copyright: { isString: true } }).remove();
|
||||
// remove private members
|
||||
data({ access: 'private' }).remove();
|
||||
// remove ignored doclets
|
||||
data({ ignore: true }).remove();
|
||||
if (!fs.existsSync(opts.destination)) {
|
||||
fs.mkdirSync(opts.destination);
|
||||
}
|
||||
var out = new Parser_1.Parser(data().get()).emit();
|
||||
fs.writeFileSync(path.join(opts.destination, 'phaser.d.ts'), out);
|
||||
}
|
||||
exports.publish = publish;
|
||||
;
|
||||
//# sourceMappingURL=publish.js.map
|
1
scripts/tsgen/bin/publish.js.map
Normal file
1
scripts/tsgen/bin/publish.js.map
Normal file
|
@ -0,0 +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"}
|
71
scripts/tsgen/jsdoc-plugins/this.js
Normal file
71
scripts/tsgen/jsdoc-plugins/this.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
var logger = require('jsdoc/util/logger');
|
||||
|
||||
exports.handlers = {
|
||||
|
||||
/*
|
||||
From:
|
||||
|
||||
"returns": [
|
||||
{
|
||||
"type": {
|
||||
"names": [
|
||||
"this"
|
||||
],
|
||||
"parsedType": {
|
||||
"type": "NameExpression",
|
||||
"name": "this",
|
||||
"reservedWord": true
|
||||
}
|
||||
},
|
||||
"description": "This Game Object instance."
|
||||
}
|
||||
],
|
||||
|
||||
To:
|
||||
|
||||
"returns": [
|
||||
{
|
||||
"type": {
|
||||
"names": [
|
||||
"Phaser.GameObjects.GameObject"
|
||||
],
|
||||
"parsedType": {
|
||||
"type": "NameExpression",
|
||||
"name": "Phaser.GameObjects.GameObject"
|
||||
}
|
||||
},
|
||||
"description": "This Game Object instance."
|
||||
}
|
||||
],
|
||||
|
||||
*/
|
||||
|
||||
// The processingComplete event is fired after JSDoc updates the parse results to reflect inherited and borrowed symbols.
|
||||
processingComplete: function (e)
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
e.doclets.forEach(function(doclet) {
|
||||
|
||||
if (Array.isArray(doclet.returns))
|
||||
{
|
||||
var entry = doclet.returns[0];
|
||||
|
||||
if (entry.type.names[0] === 'this')
|
||||
{
|
||||
count++;
|
||||
entry.type.names[0] = doclet.memberof;
|
||||
}
|
||||
|
||||
if (entry.type.parsedType && entry.type.parsedType.name === 'this')
|
||||
{
|
||||
entry.type.parsedType.name = doclet.memberof;
|
||||
entry.type.parsedType.reservedWord = false;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// logger.warn('converted ' + count);
|
||||
}
|
||||
};
|
11
scripts/tsgen/jsdoc-plugins/typedef.js
Normal file
11
scripts/tsgen/jsdoc-plugins/typedef.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
exports.handlers = {
|
||||
beforeParse: function(e) {
|
||||
|
||||
// replace {?[type]} with {?any}
|
||||
e.source = e.source.replace(/{\?\[type\]}/g, '{any}');
|
||||
|
||||
// replace {[type]} with {any}
|
||||
e.source = e.source.replace(/{\[type\]}/g, '{any}');
|
||||
|
||||
}
|
||||
};
|
33
scripts/tsgen/jsdoc-tsd.conf.json
Normal file
33
scripts/tsgen/jsdoc-tsd.conf.json
Normal file
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"tags": {
|
||||
"allowUnknownTags": true
|
||||
},
|
||||
"source": {
|
||||
"include": [
|
||||
"../../src/",
|
||||
"../../plugins/fbinstant/src"
|
||||
],
|
||||
"exclude": [
|
||||
"../../src/phaser-arcade-physics.js",
|
||||
"../../src/phaser-core.js",
|
||||
"../../src/physics/matter-js/poly-decomp/",
|
||||
"../../src/physics/matter-js/lib",
|
||||
"../../src/polyfills"
|
||||
],
|
||||
"includePattern": ".+\\.js?$",
|
||||
"excludePattern": "(^|\\/|\\\\)_"
|
||||
},
|
||||
"plugins": ["./jsdoc-plugins/typedef"],
|
||||
"opts": {
|
||||
"debug": true,
|
||||
"template": "./bin/",
|
||||
"encoding": "utf8",
|
||||
"destination": "../../types/",
|
||||
"outputSourceFiles": false,
|
||||
"outputSourcePath": true,
|
||||
"recurse": true,
|
||||
"private": false,
|
||||
"lenient": true,
|
||||
"sourceType": "script"
|
||||
}
|
||||
}
|
589
scripts/tsgen/src/Parser.ts
Normal file
589
scripts/tsgen/src/Parser.ts
Normal file
|
@ -0,0 +1,589 @@
|
|||
import * as dom from 'dts-dom';
|
||||
|
||||
const regexEndLine = /^(.*)\r\n|\n|\r/gm;
|
||||
|
||||
export class Parser {
|
||||
|
||||
topLevel: dom.TopLevelDeclaration[];
|
||||
objects: { [key: string]: dom.DeclarationBase };
|
||||
namespaces: { [key: string]: dom.NamespaceDeclaration };
|
||||
|
||||
constructor(docs: any[]) {
|
||||
|
||||
this.topLevel = [];
|
||||
this.objects = {};
|
||||
this.namespaces = {};
|
||||
|
||||
// parse doclets and create corresponding dom objects
|
||||
this.parseObjects(docs);
|
||||
|
||||
this.resolveObjects(docs);
|
||||
|
||||
// removes members inherited from classes
|
||||
// possibly could be avoided if mixins were defined as such before JSDoc parses them and then we could globally remove all inherited (not
|
||||
// overriden) members globally from the parsed DB
|
||||
this.resolveInheritance(docs);
|
||||
|
||||
this.resolveParents(docs);
|
||||
|
||||
// add integer alias
|
||||
this.topLevel.push(dom.create.alias('integer', dom.type.number));
|
||||
|
||||
// add declare module
|
||||
const phaserPkgModuleDOM = dom.create.module('phaser');
|
||||
phaserPkgModuleDOM.members.push(dom.create.exportEquals('Phaser'));
|
||||
this.topLevel.push(phaserPkgModuleDOM);
|
||||
}
|
||||
|
||||
emit() {
|
||||
let ignored = [];
|
||||
let result = this.topLevel.reduce((out: string, obj: dom.TopLevelDeclaration) => {
|
||||
// TODO: remove once stable
|
||||
// if (<string>obj.kind === 'property') {
|
||||
// ignored.push((<any>obj).name);
|
||||
// return out;
|
||||
// }
|
||||
//////////////////////////
|
||||
return out + dom.emit(obj);
|
||||
}, '');
|
||||
|
||||
if (ignored.length > 0)
|
||||
{
|
||||
console.log('ignored top level properties:');
|
||||
console.log(ignored);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private parseObjects(docs: any[]) {
|
||||
for (let i = 0; i < docs.length; i++) {
|
||||
|
||||
let doclet = docs[i];
|
||||
|
||||
// TODO: Custom temporary rules
|
||||
switch (doclet.longname)
|
||||
{
|
||||
case 'Phaser.GameObjects.Components.Alpha':
|
||||
case 'Phaser.GameObjects.Components.Animation':
|
||||
case 'Phaser.GameObjects.Components.BlendMode':
|
||||
case 'Phaser.GameObjects.Components.ComputedSize':
|
||||
case 'Phaser.GameObjects.Components.Crop':
|
||||
case 'Phaser.GameObjects.Components.Depth':
|
||||
case 'Phaser.GameObjects.Components.Flip':
|
||||
case 'Phaser.GameObjects.Components.GetBounds':
|
||||
case 'Phaser.GameObjects.Components.Mask':
|
||||
case 'Phaser.GameObjects.Components.Origin':
|
||||
case 'Phaser.GameObjects.Components.PathFollower':
|
||||
case 'Phaser.GameObjects.Components.Pipeline':
|
||||
case 'Phaser.GameObjects.Components.ScrollFactor':
|
||||
case 'Phaser.GameObjects.Components.Size':
|
||||
case 'Phaser.GameObjects.Components.Texture':
|
||||
case 'Phaser.GameObjects.Components.TextureCrop':
|
||||
case 'Phaser.GameObjects.Components.Tint':
|
||||
case 'Phaser.GameObjects.Components.ToJSON':
|
||||
case 'Phaser.GameObjects.Components.Transform':
|
||||
case 'Phaser.GameObjects.Components.Visible':
|
||||
case 'Phaser.Renderer.WebGL.Pipelines.ModelViewProjection':
|
||||
doclet.kind = 'mixin';
|
||||
break;
|
||||
|
||||
// Because, sod you TypeScript
|
||||
case 'Phaser.BlendModes':
|
||||
case 'Phaser.ScaleModes':
|
||||
case 'Phaser.Physics.Impact.TYPE':
|
||||
case 'Phaser.Physics.Impact.COLLIDES':
|
||||
case 'Phaser.Scale.Center':
|
||||
case 'Phaser.Scale.Orientation':
|
||||
case 'Phaser.Scale.ScaleModes':
|
||||
case 'Phaser.Scale.Zoom':
|
||||
case 'Phaser.Textures.FilterMode':
|
||||
// console.log('Forcing enum for ' + doclet.longname);
|
||||
doclet.kind = 'member';
|
||||
doclet.isEnum = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((doclet.longname.indexOf('Phaser.Physics.Arcade.Components.') == 0 || doclet.longname.indexOf('Phaser.Physics.Impact.Components.') == 0 || doclet.longname.indexOf('Phaser.Physics.Matter.Components.') == 0) && doclet.longname.indexOf('#') == -1)
|
||||
{
|
||||
doclet.kind = 'mixin';
|
||||
}
|
||||
|
||||
let obj: dom.DeclarationBase;
|
||||
let container = this.objects;
|
||||
|
||||
switch (doclet.kind) {
|
||||
case 'namespace':
|
||||
obj = this.createNamespace(doclet);
|
||||
container = this.namespaces;
|
||||
break;
|
||||
case 'class':
|
||||
obj = this.createClass(doclet);
|
||||
break;
|
||||
case 'mixin':
|
||||
obj = this.createInterface(doclet);
|
||||
break;
|
||||
case 'member':
|
||||
if (doclet.isEnum === true) {
|
||||
obj = this.createEnum(doclet);
|
||||
break;
|
||||
}
|
||||
case 'constant':
|
||||
obj = this.createMember(doclet);
|
||||
break;
|
||||
case 'function':
|
||||
obj = this.createFunction(doclet);
|
||||
break;
|
||||
case 'typedef':
|
||||
obj = this.createTypedef(doclet);
|
||||
break;
|
||||
case 'event':
|
||||
obj = this.createEvent(doclet);
|
||||
break;
|
||||
default:
|
||||
console.log('Ignored doclet kind: ' + doclet.kind);
|
||||
break;
|
||||
}
|
||||
|
||||
if (obj) {
|
||||
if (container[doclet.longname]) {
|
||||
console.log('Warning: ignoring duplicate doc name: ' + doclet.longname);
|
||||
docs.splice(i--, 1);
|
||||
continue;
|
||||
}
|
||||
container[doclet.longname] = obj;
|
||||
if (doclet.description) {
|
||||
let otherDocs = obj.jsDocComment || '';
|
||||
obj.jsDocComment = doclet.description.replace(regexEndLine, '$1\n') + otherDocs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private resolveObjects(docs: any[]) {
|
||||
let allTypes = new Set<string>();
|
||||
for (let doclet of docs) {
|
||||
let obj = doclet.kind === 'namespace' ? this.namespaces[doclet.longname] : this.objects[doclet.longname];
|
||||
|
||||
if (!obj) {
|
||||
|
||||
// TODO
|
||||
console.log(`Warning: Didn't find object for ${doclet.longname}`);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!doclet.memberof) {
|
||||
this.topLevel.push(obj as dom.TopLevelDeclaration);
|
||||
} else {
|
||||
let isNamespaceMember = doclet.kind === 'class' || doclet.kind === 'typedef' || doclet.kind == 'namespace' || doclet.isEnum;
|
||||
let parent = isNamespaceMember ? this.namespaces[doclet.memberof] : (this.objects[doclet.memberof] || this.namespaces[doclet.memberof]);
|
||||
|
||||
//TODO: this whole section should be removed once stable
|
||||
if (!parent) {
|
||||
console.log(`${doclet.longname} in ${doclet.meta.filename}@${doclet.meta.lineno} has parent '${doclet.memberof}' that is not defined.`);
|
||||
let parts: string[] = doclet.memberof.split('.');
|
||||
let newParts = [parts.pop()];
|
||||
while (parts.length > 0 && this.objects[parts.join('.')] == null) newParts.unshift(parts.pop());
|
||||
parent = this.objects[parts.join('.')] as dom.NamespaceDeclaration;
|
||||
if (parent == null) {
|
||||
parent = dom.create.namespace(doclet.memberof);
|
||||
this.namespaces[doclet.memberof] = <dom.NamespaceDeclaration>parent;
|
||||
this.topLevel.push(<dom.NamespaceDeclaration>parent);
|
||||
} else {
|
||||
while (newParts.length > 0) {
|
||||
let oldParent = <dom.NamespaceDeclaration>parent;
|
||||
parent = dom.create.namespace(newParts.shift());
|
||||
parts.push((<dom.NamespaceDeclaration>parent).name);
|
||||
this.namespaces[parts.join('.')] = <dom.NamespaceDeclaration>parent;
|
||||
oldParent.members.push(<dom.NamespaceDeclaration>parent);
|
||||
(<any>parent)._parent = oldParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
if ((<any>parent).members) {
|
||||
(<any>parent).members.push(obj);
|
||||
} else {
|
||||
console.log('Cannot find members array for:');
|
||||
console.log(parent);
|
||||
}
|
||||
|
||||
(<any>obj)._parent = parent;
|
||||
|
||||
// class/interface members have methods, not functions
|
||||
if (((parent as any).kind === 'class' || (parent as any).kind === 'interface')
|
||||
&& (obj as any).kind === 'function')
|
||||
(obj as any).kind = 'method';
|
||||
// namespace members are vars or consts, not properties
|
||||
if ((parent as any).kind === 'namespace' && (obj as any).kind === 'property') {
|
||||
if (doclet.kind == 'constant') (obj as any).kind = 'const';
|
||||
else (obj as any).kind = 'var';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private resolveInheritance(docs: any[]) {
|
||||
for (let doclet of docs) {
|
||||
let obj = doclet.kind === 'namespace' ? this.namespaces[doclet.longname] : this.objects[doclet.longname];
|
||||
if (!obj) {
|
||||
|
||||
// TODO
|
||||
console.log(`Didn't find type ${doclet.longname} ???`);
|
||||
|
||||
continue;
|
||||
}
|
||||
if (!(<any>obj)._parent) continue;
|
||||
|
||||
if (doclet.inherited) {// remove inherited members if they aren't from an interface
|
||||
let from = this.objects[doclet.inherits];
|
||||
if (!from || !(<any>from)._parent)
|
||||
throw `'${doclet.longname}' should inherit from '${doclet.inherits}', which is not defined.`;
|
||||
|
||||
if ((<any>from)._parent.kind != 'interface') {
|
||||
(<any>obj)._parent.members.splice((<any>obj)._parent.members.indexOf(obj), 1);
|
||||
(<any>obj)._parent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private resolveParents(docs: any[]) {
|
||||
for (let doclet of docs) {
|
||||
let obj = this.objects[doclet.longname];
|
||||
if (!obj || doclet.kind !== 'class') continue;
|
||||
|
||||
let o = obj as dom.ClassDeclaration;
|
||||
|
||||
// resolve augments
|
||||
if (doclet.augments && doclet.augments.length) {
|
||||
for (let augment of doclet.augments) {
|
||||
let name: string = this.prepareTypeName(augment);
|
||||
|
||||
let wrappingName = name.match(/[^<]+/s)[0];//gets everything up to a first < (to handle augments with type parameters)
|
||||
|
||||
let baseType = this.objects[wrappingName] as dom.ClassDeclaration | dom.InterfaceDeclaration;
|
||||
|
||||
if (!baseType) {
|
||||
console.log(`ERROR: Did not find base type: ${augment} for ${doclet.longname}`);
|
||||
} else {
|
||||
if (baseType.kind == 'class') {
|
||||
o.baseType = dom.create.class(name);
|
||||
} else {
|
||||
o.implements.push(dom.create.interface(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private createNamespace(doclet: any): dom.NamespaceDeclaration {
|
||||
|
||||
/**
|
||||
namespace: { comment: '',
|
||||
meta:
|
||||
{ filename: 'index.js',
|
||||
lineno: 10,
|
||||
columnno: 0,
|
||||
path: '/Users/rich/Documents/GitHub/phaser/src/tweens',
|
||||
code: {} },
|
||||
kind: 'namespace',
|
||||
name: 'Tweens',
|
||||
memberof: 'Phaser',
|
||||
longname: 'Phaser.Tweens',
|
||||
scope: 'static',
|
||||
___id: 'T000002R034468',
|
||||
___s: true }
|
||||
*/
|
||||
|
||||
// console.log('namespace:', doclet.longname);
|
||||
|
||||
let obj = dom.create.namespace(doclet.name);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private createClass(doclet: any): dom.ClassDeclaration {
|
||||
let obj = dom.create.class(doclet.name);
|
||||
|
||||
let params = null;
|
||||
if (doclet.params) {
|
||||
let ctor = dom.create.constructor(null);
|
||||
this.setParams(doclet, ctor);
|
||||
params = ctor.parameters;
|
||||
|
||||
obj.members.push(ctor);
|
||||
(<any>ctor)._parent = obj;
|
||||
}
|
||||
|
||||
this.processGeneric(doclet, obj, params);
|
||||
|
||||
if (doclet.classdesc)
|
||||
doclet.description = doclet.classdesc.replace(regexEndLine, '$1\n'); // make sure docs will be added
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private createInterface(doclet: any): dom.InterfaceDeclaration {
|
||||
return dom.create.interface(doclet.name);
|
||||
}
|
||||
|
||||
private createMember(doclet: any): dom.PropertyDeclaration {
|
||||
let type = this.parseType(doclet);
|
||||
|
||||
let obj = dom.create.property(doclet.name, type);
|
||||
|
||||
this.processGeneric(doclet, obj, null);
|
||||
|
||||
this.processFlags(doclet, obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private createEvent(doclet: any): dom.ConstDeclaration {
|
||||
|
||||
let type = this.parseType(doclet);
|
||||
|
||||
let obj = dom.create.const(doclet.name, type);
|
||||
|
||||
this.processFlags(doclet, obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private createEnum(doclet: any): dom.EnumDeclaration {
|
||||
let obj = dom.create.enum(doclet.name, false);
|
||||
|
||||
this.processFlags(doclet, obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private createFunction(doclet: any): dom.FunctionDeclaration {
|
||||
let returnType: dom.Type = dom.type.void;
|
||||
|
||||
if (doclet.returns) {
|
||||
returnType = this.parseType(doclet.returns[0]);
|
||||
}
|
||||
|
||||
let obj = dom.create.function(doclet.name, null, returnType);
|
||||
this.setParams(doclet, obj);
|
||||
|
||||
this.processGeneric(doclet, obj, obj.parameters);
|
||||
|
||||
this.processFlags(doclet, obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private createTypedef(doclet: any): dom.TypeAliasDeclaration {
|
||||
const typeName = doclet.type.names[0];
|
||||
let type = null;
|
||||
|
||||
if (doclet.type.names[0] === 'object') {
|
||||
let properties = [];
|
||||
|
||||
for (let propDoc of doclet.properties) {
|
||||
let prop = this.createMember(propDoc);
|
||||
properties.push(prop);
|
||||
if (propDoc.description)
|
||||
prop.jsDocComment = propDoc.description.replace(regexEndLine, '$1\n');
|
||||
}
|
||||
|
||||
type = dom.create.objectType(properties);
|
||||
|
||||
if (doclet.augments && doclet.augments.length) {
|
||||
let intersectionTypes = [];
|
||||
for (let i = 0; i < doclet.augments.length; i++) {
|
||||
intersectionTypes.push(dom.create.namedTypeReference(doclet.augments[i]));
|
||||
}
|
||||
intersectionTypes.push(type);
|
||||
type = dom.create.intersection(intersectionTypes);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (doclet.type.names[0] == "function") {
|
||||
type = dom.create.functionType(null, dom.type.void);
|
||||
this.setParams(doclet, type);
|
||||
} else {
|
||||
type = this.parseType(doclet);
|
||||
}
|
||||
}
|
||||
|
||||
let alias = dom.create.alias(doclet.name, type);
|
||||
|
||||
this.processGeneric(doclet, alias, null);
|
||||
|
||||
return alias;
|
||||
}
|
||||
|
||||
private setParams(doclet: any, obj: dom.FunctionDeclaration | dom.ConstructorDeclaration): void {
|
||||
let parameters: dom.Parameter[] = [];
|
||||
|
||||
if (doclet.params) {
|
||||
|
||||
let optional = false;
|
||||
|
||||
obj.jsDocComment = '';
|
||||
|
||||
for (let paramDoc of doclet.params) {
|
||||
|
||||
// TODO REMOVE TEMP FIX
|
||||
if (paramDoc.name.indexOf('.') != -1) {
|
||||
console.log(`Warning: ignoring param with '.' for '${doclet.longname}' in ${doclet.meta.filename}@${doclet.meta.lineno}`);
|
||||
|
||||
let defaultVal = paramDoc.defaultvalue !== undefined ? ` Default ${String(paramDoc.defaultvalue)}.` : '';
|
||||
if (paramDoc.description)
|
||||
obj.jsDocComment += `\n@param ${paramDoc.name} ${paramDoc.description.replace(regexEndLine, '$1\n')}` + defaultVal;
|
||||
else if (defaultVal.length)
|
||||
obj.jsDocComment += `\n@param ${paramDoc.name} ` + defaultVal;
|
||||
continue;
|
||||
}
|
||||
///////////////////////
|
||||
|
||||
let param = dom.create.parameter(paramDoc.name, this.parseType(paramDoc));
|
||||
parameters.push(param);
|
||||
|
||||
if (optional && paramDoc.optional != true) {
|
||||
console.log(`Warning: correcting to optional: parameter '${paramDoc.name}' for '${doclet.longname}' in ${doclet.meta.filename}@${doclet.meta.lineno}`);
|
||||
paramDoc.optional = true;
|
||||
}
|
||||
|
||||
this.processFlags(paramDoc, param);
|
||||
|
||||
optional = optional || paramDoc.optional === true;
|
||||
|
||||
let defaultVal = paramDoc.defaultvalue !== undefined ? ` Default ${String(paramDoc.defaultvalue)}.` : '';
|
||||
|
||||
if (paramDoc.description)
|
||||
obj.jsDocComment += `\n@param ${paramDoc.name} ${paramDoc.description.replace(regexEndLine, '$1\n')}` + defaultVal;
|
||||
else if (defaultVal.length)
|
||||
obj.jsDocComment += `\n@param ${paramDoc.name} ` + defaultVal;
|
||||
}
|
||||
}
|
||||
|
||||
obj.parameters = parameters;
|
||||
}
|
||||
|
||||
private parseType(typeDoc: any): dom.Type {
|
||||
if (!typeDoc || !typeDoc.type) {
|
||||
return dom.type.any;
|
||||
} else {
|
||||
let types = [];
|
||||
for (let name of typeDoc.type.names) {
|
||||
|
||||
name = this.prepareTypeName(name);
|
||||
|
||||
let type = dom.create.namedTypeReference(this.processTypeName(name));
|
||||
|
||||
types.push(type);
|
||||
}
|
||||
if (types.length == 1) return types[0];
|
||||
else return dom.create.union(types);
|
||||
}
|
||||
}
|
||||
|
||||
private prepareTypeName(name: string): string {
|
||||
if (name.indexOf('*') != -1) {
|
||||
name = (<string>name).split('*').join('any');
|
||||
}
|
||||
if (name.indexOf('.<') != -1 && name !== 'Array.<function()>') {
|
||||
name = (<string>name).split('.<').join('<');
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private processTypeName(name: string): string {
|
||||
if (name === 'float') return 'number';
|
||||
if (name === 'function') return 'Function';
|
||||
if (name === 'Array.<function()>') return 'Function[]';
|
||||
if (name === 'array') return 'any[]';
|
||||
|
||||
if (name.startsWith('Array<')) {
|
||||
let matches = name.match(/^Array<(.*)>$/);
|
||||
|
||||
if (matches && matches[1]) {
|
||||
return this.processTypeName(matches[1]) + '[]';
|
||||
}
|
||||
} else if (name.startsWith('Object<')) {
|
||||
let matches = name.match(/^Object<(.*)>$/);
|
||||
|
||||
if (matches && matches[1]) {
|
||||
if (matches[1].indexOf(',') != -1) {
|
||||
let parts = matches[1].split(',');
|
||||
return `{[key: ${this.processTypeName(parts[0])}]: ${this.processTypeName(parts[1])}}`;
|
||||
} else {
|
||||
return `{[key: string]: ${this.processTypeName(matches[1])}}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
private processFlags(doclet: any, obj: dom.DeclarationBase | dom.Parameter) {
|
||||
obj.flags = dom.DeclarationFlags.None;
|
||||
if (doclet.variable === true) {
|
||||
obj.flags |= dom.ParameterFlags.Rest;
|
||||
let type: any = (<dom.Parameter>obj).type;
|
||||
if (!type.name.endsWith('[]')) {
|
||||
if (type.name != 'any')
|
||||
console.log(`Warning: rest parameter should be an array type for ${doclet.longname}`);
|
||||
type.name = type.name + '[]'; // Must be an array
|
||||
}
|
||||
} else if (doclet.optional === true) {// Rest implies Optional – no need to flag it as such
|
||||
if (obj['kind'] === 'parameter') obj.flags |= dom.ParameterFlags.Optional;
|
||||
else obj.flags |= dom.DeclarationFlags.Optional;
|
||||
}
|
||||
switch (doclet.access) {
|
||||
case 'protected':
|
||||
obj.flags |= dom.DeclarationFlags.Protected;
|
||||
break;
|
||||
case 'private':
|
||||
obj.flags |= dom.DeclarationFlags.Private;
|
||||
break;
|
||||
}
|
||||
if (doclet.readonly || doclet.kind === 'constant') obj.flags |= dom.DeclarationFlags.ReadOnly;
|
||||
if (doclet.scope === 'static') obj.flags |= dom.DeclarationFlags.Static;
|
||||
}
|
||||
|
||||
private processGeneric(doclet: any, obj: dom.ClassDeclaration | dom.FunctionDeclaration | dom.PropertyDeclaration | dom.TypeAliasDeclaration, params: dom.Parameter[]) {
|
||||
if (doclet.tags)
|
||||
for (let tag of doclet.tags) {
|
||||
if (tag.originalTitle === 'generic') {
|
||||
let matches = (<string>tag.value).match(/(?:(?:{)([^}]+)(?:}))?\s?([^\s]+)(?:\s?-\s?(?:\[)(.+)(?:\]))?/);
|
||||
let typeParam = dom.create.typeParameter(matches[2], matches[1] == null ? null : dom.create.typeParameter(matches[1]));
|
||||
(<dom.ClassDeclaration | dom.FunctionDeclaration | dom.TypeAliasDeclaration>obj).typeParameters.push(typeParam);
|
||||
handleOverrides(matches[3], matches[2]);
|
||||
} else if (tag.originalTitle === 'genericUse') {
|
||||
let matches = (<string>tag.value).match(/(?:(?:{)([^}]+)(?:}))(?:\s?-\s?(?:\[)(.+)(?:\]))?/);
|
||||
let overrideType: string = this.prepareTypeName(matches[1]);
|
||||
|
||||
handleOverrides(matches[2], this.processTypeName(overrideType));
|
||||
}
|
||||
}
|
||||
|
||||
function handleOverrides(matchedString: string, overrideType: string) {
|
||||
if (matchedString != null) {
|
||||
let overrides = matchedString.split(',');
|
||||
if (params != null) {
|
||||
for (let param of params) {
|
||||
if (overrides.indexOf(param.name) != -1) {
|
||||
param.type = dom.create.namedTypeReference(overrideType);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (overrides.indexOf('$return') != -1) {// has $return, must be a function
|
||||
(<dom.FunctionDeclaration>obj).returnType = dom.create.namedTypeReference(overrideType);
|
||||
}
|
||||
if (overrides.indexOf('$type') != -1) {// has $type, must be a property
|
||||
(<dom.PropertyDeclaration>obj).type = dom.create.namedTypeReference(overrideType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
24
scripts/tsgen/src/publish.ts
Normal file
24
scripts/tsgen/src/publish.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import * as fs from 'fs-extra';
|
||||
import * as path from 'path';
|
||||
import { Parser } from './Parser';
|
||||
|
||||
export function publish(data: any, opts: any) {
|
||||
// remove undocumented stuff.
|
||||
data({ undocumented: true }).remove();
|
||||
// remove package data
|
||||
data({ kind: 'package' }).remove();
|
||||
// remove header comments
|
||||
data({ copyright: { isString: true } }).remove();
|
||||
// remove private members
|
||||
data({ access: 'private' }).remove();
|
||||
// remove ignored doclets
|
||||
data({ ignore: true }).remove();
|
||||
|
||||
if (!fs.existsSync(opts.destination)) {
|
||||
fs.mkdirSync(opts.destination);
|
||||
}
|
||||
|
||||
var out = new Parser(data().get()).emit();
|
||||
|
||||
fs.writeFileSync(path.join(opts.destination, 'phaser.d.ts'), out);
|
||||
};
|
39
scripts/tsgen/test/bin/game.js
Normal file
39
scripts/tsgen/test/bin/game.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var MyScene = /** @class */ (function (_super) {
|
||||
__extends(MyScene, _super);
|
||||
function MyScene() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
MyScene.prototype.preload = function () {
|
||||
this.load.atlas('cards', 'assets/atlas/cards.png', 'assets/atlas/cards.json');
|
||||
};
|
||||
MyScene.prototype.create = function () {
|
||||
var sprite = this.add.sprite(400, 300, 'cards', 'clubs3');
|
||||
sprite.setInteractive();
|
||||
this.input.on('pointerdown', function () {
|
||||
sprite.setFrame('hearts4');
|
||||
});
|
||||
};
|
||||
return MyScene;
|
||||
}(Phaser.Scene));
|
||||
var config = {
|
||||
type: Phaser.AUTO,
|
||||
parent: 'phaser-example',
|
||||
width: 800,
|
||||
height: 600,
|
||||
scene: MyScene
|
||||
};
|
||||
var game = new Phaser.Game(config);
|
||||
//# sourceMappingURL=game.js.map
|
1
scripts/tsgen/test/bin/game.js.map
Normal file
1
scripts/tsgen/test/bin/game.js.map
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"game.js","sourceRoot":"","sources":["../src/game.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA;IAAsB,2BAAY;IAAlC;;IAoBA,CAAC;IAlBU,yBAAO,GAAd;QAEI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,CAAC,CAAC;IAClF,CAAC;IAEM,wBAAM,GAAb;QAEI,IAAI,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAE1D,MAAM,CAAC,cAAc,EAAE,CAAC;QAExB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,EAAE;YAEzB,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAE/B,CAAC,CAAC,CAAC;IACP,CAAC;IAEL,cAAC;AAAD,CAAC,AApBD,CAAsB,MAAM,CAAC,KAAK,GAoBjC;AAED,IAAI,MAAM,GAAG;IACT,IAAI,EAAE,MAAM,CAAC,IAAI;IACjB,MAAM,EAAE,gBAAgB;IACxB,KAAK,EAAE,GAAG;IACV,MAAM,EAAE,GAAG;IACX,KAAK,EAAE,OAAO;CACjB,CAAC;AAEF,IAAI,IAAI,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC"}
|
0
scripts/tsgen/test/output.txt
Normal file
0
scripts/tsgen/test/output.txt
Normal file
31
scripts/tsgen/test/src/game.ts
Normal file
31
scripts/tsgen/test/src/game.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
class MyScene extends Phaser.Scene {
|
||||
|
||||
public preload ()
|
||||
{
|
||||
this.load.atlas('cards', 'assets/atlas/cards.png', 'assets/atlas/cards.json');
|
||||
}
|
||||
|
||||
public create ()
|
||||
{
|
||||
let sprite = this.add.sprite(400, 300, 'cards', 'clubs3');
|
||||
|
||||
sprite.setInteractive();
|
||||
|
||||
this.input.on('pointerdown', function () {
|
||||
|
||||
sprite.setFrame('hearts4');
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let config = {
|
||||
type: Phaser.AUTO,
|
||||
parent: 'phaser-example',
|
||||
width: 800,
|
||||
height: 600,
|
||||
scene: MyScene
|
||||
};
|
||||
|
||||
let game = new Phaser.Game(config);
|
35
scripts/tsgen/test/src/game2.ts
Normal file
35
scripts/tsgen/test/src/game2.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
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();
|
24
scripts/tsgen/test/tsconfig.json
Normal file
24
scripts/tsgen/test/tsconfig.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "system",
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitReturns": true,
|
||||
"preserveConstEnums": true,
|
||||
"outFile": "./bin/game.js",
|
||||
"sourceMap": true,
|
||||
"lib": [
|
||||
"dom",
|
||||
"scripthost",
|
||||
"es5"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/game.ts",
|
||||
"../../../types/phaser.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
16
scripts/tsgen/tsconfig.json
Normal file
16
scripts/tsgen/tsconfig.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"version": "0.0.1",
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"declaration": false,
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": true,
|
||||
"outDir": "./bin/"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"./node_modules/@types/**/*.d.ts"
|
||||
]
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var PropertyValueInc = require('./PropertyValueInc');
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback CallCallback
|
||||
*
|
||||
* @param {Phaser.GameObjects.GameObject} item - The Game Object to run the callback on.
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -19,7 +13,7 @@
|
|||
* @generic {Phaser.GameObjects.GameObject[]} G - [items,$return]
|
||||
*
|
||||
* @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action.
|
||||
* @param {CallCallback} callback - The callback to be invoked. It will be passed just one argument: the item from the array.
|
||||
* @param {Phaser.Types.Actions.CallCallback} callback - The callback to be invoked. It will be passed just one argument: the item from the array.
|
||||
* @param {*} context - The scope in which the callback will be invoked.
|
||||
*
|
||||
* @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that was passed to this Action.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var AlignIn = require('../display/align/in/QuickSet');
|
||||
|
@ -12,20 +12,6 @@ var Zone = require('../gameobjects/zone/Zone');
|
|||
|
||||
var tempZone = new Zone({ sys: { queueDepthSort: NOOP, events: { once: NOOP } } }, 0, 0, 1, 1);
|
||||
|
||||
/**
|
||||
* @typedef {object} GridAlignConfig
|
||||
*
|
||||
* @property {integer} [width=-1] - The width of the grid in items (not pixels). -1 means lay all items out horizontally, regardless of quantity.
|
||||
* If both this value and height are set to -1 then this value overrides it and the `height` value is ignored.
|
||||
* @property {integer} [height=-1] - The height of the grid in items (not pixels). -1 means lay all items out vertically, regardless of quantity.
|
||||
* If both this value and `width` are set to -1 then `width` overrides it and this value is ignored.
|
||||
* @property {integer} [cellWidth=1] - The width of the cell, in pixels, in which the item is positioned.
|
||||
* @property {integer} [cellHeight=1] - The height of the cell, in pixels, in which the item is positioned.
|
||||
* @property {integer} [position=0] - The alignment position. One of the Phaser.Display.Align consts such as `TOP_LEFT` or `RIGHT_CENTER`.
|
||||
* @property {number} [x=0] - Optionally place the top-left of the final grid at this coordinate.
|
||||
* @property {number} [y=0] - Optionally place the top-left of the final grid at this coordinate.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Takes an array of Game Objects, or any objects that have public `x` and `y` properties,
|
||||
* and then aligns them based on the grid configuration given to this action.
|
||||
|
@ -36,7 +22,7 @@ var tempZone = new Zone({ sys: { queueDepthSort: NOOP, events: { once: NOOP } }
|
|||
* @generic {Phaser.GameObjects.GameObject[]} G - [items,$return]
|
||||
*
|
||||
* @param {(array|Phaser.GameObjects.GameObject[])} items - The array of items to be updated by this action.
|
||||
* @param {GridAlignConfig} options - The GridAlign Configuration object.
|
||||
* @param {Phaser.Types.Actions.GridAlignConfig} options - The GridAlign Configuration object.
|
||||
*
|
||||
* @return {(array|Phaser.GameObjects.GameObject[])} The array of objects that were passed to this Action.
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var PropertyValueInc = require('./PropertyValueInc');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var PropertyValueInc = require('./PropertyValueInc');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var PropertyValueInc = require('./PropertyValueInc');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var PropertyValueInc = require('./PropertyValueInc');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var GetPoints = require('../geom/line/GetPoints');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var MarchingAnts = require('../geom/rectangle/MarchingAnts');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
var BresenhamPoints = require('../geom/line/BresenhamPoints');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @author Richard Davey <rich@photonstorm.com>
|
||||
* @copyright 2018 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
* @copyright 2019 Photon Storm Ltd.
|
||||
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue